LCOV - code coverage report
Current view: top level - xmlscript/source/xml_helper - xml_impctx.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 261 0.0 %
Date: 2014-04-14 Functions: 0 45 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             : 
      20             : #include "xml_import.hxx"
      21             : 
      22             : #include <cppuhelper/factory.hxx>
      23             : #include <cppuhelper/implementationentry.hxx>
      24             : #include <cppuhelper/implbase1.hxx>
      25             : #include <cppuhelper/implbase4.hxx>
      26             : #include <cppuhelper/supportsservice.hxx>
      27             : #include <com/sun/star/xml/input/XAttributes.hpp>
      28             : #include <com/sun/star/lang/XInitialization.hpp>
      29             : #include <com/sun/star/uno/XComponentContext.hpp>
      30             : #include <com/sun/star/lang/XServiceInfo.hpp>
      31             : #include <vector>
      32             : #include <boost/unordered_map.hpp>
      33             : 
      34             : #include <memory>
      35             : 
      36             : using namespace ::rtl;
      37             : using namespace ::osl;
      38             : using namespace ::com::sun::star;
      39             : using namespace ::com::sun::star::uno;
      40             : 
      41             : namespace xmlscript
      42             : {
      43             : 
      44             : const sal_Int32 UID_UNKNOWN = -1;
      45             : 
      46           0 : Sequence< OUString > getSupportedServiceNames_DocumentHandlerImpl()
      47             : {
      48           0 :     OUString name( "com.sun.star.xml.input.SaxDocumentHandler" );
      49           0 :     return Sequence< OUString >( &name, 1 );
      50             : }
      51             : 
      52           0 : OUString getImplementationName_DocumentHandlerImpl()
      53             : {
      54           0 :     return OUString( "com.sun.star.comp.xml.input.SaxDocumentHandler" );
      55             : }
      56             : 
      57             : typedef ::boost::unordered_map< OUString, sal_Int32, OUStringHash > t_OUString2LongMap;
      58             : 
      59           0 : struct PrefixEntry
      60             : {
      61             :     ::std::vector< sal_Int32 > m_Uids;
      62             : 
      63           0 :     inline PrefixEntry() SAL_THROW(())
      64           0 :         { m_Uids.reserve( 4 ); }
      65             : };
      66             : 
      67             : typedef ::boost::unordered_map<
      68             :     OUString, PrefixEntry *, OUStringHash > t_OUString2PrefixMap;
      69             : 
      70           0 : struct ElementEntry
      71             : {
      72             :     Reference< xml::input::XElement > m_xElement;
      73             :     ::std::vector< OUString > m_prefixes;
      74             : 
      75           0 :     inline ElementEntry()
      76           0 :         { m_prefixes.reserve( 2 ); }
      77             : };
      78             : 
      79             : typedef ::std::vector< ElementEntry * > t_ElementVector;
      80             : 
      81             : class ExtendedAttributes;
      82             : 
      83             : struct MGuard
      84             : {
      85             :     Mutex * m_pMutex;
      86           0 :     explicit MGuard( Mutex * pMutex )
      87           0 :         : m_pMutex( pMutex )
      88           0 :         { if (m_pMutex) m_pMutex->acquire(); }
      89           0 :     ~MGuard() throw ()
      90           0 :         { if (m_pMutex) m_pMutex->release(); }
      91             : };
      92             : 
      93             : class DocumentHandlerImpl :
      94             :     public ::cppu::WeakImplHelper4< xml::sax::XDocumentHandler,
      95             :                                     xml::input::XNamespaceMapping,
      96             :                                     lang::XInitialization,
      97             :                                     com::sun::star::lang::XServiceInfo >
      98             : {
      99             :     friend class ExtendedAttributes;
     100             : 
     101             :     Reference< xml::input::XRoot > m_xRoot;
     102             : 
     103             :     t_OUString2LongMap m_URI2Uid;
     104             :     sal_Int32 m_uid_count;
     105             : 
     106             :     OUString m_sXMLNS_PREFIX_UNKNOWN;
     107             :     OUString m_sXMLNS;
     108             : 
     109             :     sal_Int32 m_nLastURI_lookup;
     110             :     OUString m_aLastURI_lookup;
     111             : 
     112             :     t_OUString2PrefixMap m_prefixes;
     113             :     sal_Int32 m_nLastPrefix_lookup;
     114             :     OUString m_aLastPrefix_lookup;
     115             : 
     116             :     t_ElementVector m_elements;
     117             :     sal_Int32 m_nSkipElements;
     118             : 
     119             :     Mutex * m_pMutex;
     120             : 
     121             :     inline Reference< xml::input::XElement > getCurrentElement() const;
     122             : 
     123             :     inline sal_Int32 getUidByURI( OUString const & rURI );
     124             :     inline sal_Int32 getUidByPrefix( OUString const & rPrefix );
     125             : 
     126             :     inline void pushPrefix(
     127             :         OUString const & rPrefix, OUString const & rURI );
     128             :     inline void popPrefix( OUString const & rPrefix );
     129             : 
     130             :     inline void getElementName(
     131             :         OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName );
     132             : 
     133             : public:
     134             :     DocumentHandlerImpl(
     135             :         Reference< xml::input::XRoot > const & xRoot,
     136             :         bool bSingleThreadedUse );
     137             :     virtual ~DocumentHandlerImpl() throw ();
     138             : 
     139             :     // XServiceInfo
     140             :     virtual OUString SAL_CALL getImplementationName()
     141             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     142             :     virtual sal_Bool SAL_CALL supportsService(
     143             :         OUString const & servicename )
     144             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     145             :     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
     146             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     147             : 
     148             :     // XInitialization
     149             :     virtual void SAL_CALL initialize(
     150             :         Sequence< Any > const & arguments )
     151             :         throw (Exception, std::exception) SAL_OVERRIDE;
     152             : 
     153             :     // XDocumentHandler
     154             :     virtual void SAL_CALL startDocument()
     155             :         throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
     156             :     virtual void SAL_CALL endDocument()
     157             :         throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
     158             :     virtual void SAL_CALL startElement(
     159             :         OUString const & rQElementName,
     160             :         Reference< xml::sax::XAttributeList > const & xAttribs )
     161             :         throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
     162             :     virtual void SAL_CALL endElement(
     163             :         OUString const & rQElementName )
     164             :         throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
     165             :     virtual void SAL_CALL characters(
     166             :         OUString const & rChars )
     167             :         throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
     168             :     virtual void SAL_CALL ignorableWhitespace(
     169             :         OUString const & rWhitespaces )
     170             :         throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
     171             :     virtual void SAL_CALL processingInstruction(
     172             :         OUString const & rTarget, OUString const & rData )
     173             :         throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
     174             :     virtual void SAL_CALL setDocumentLocator(
     175             :         Reference< xml::sax::XLocator > const & xLocator )
     176             :         throw (xml::sax::SAXException, RuntimeException, std::exception) SAL_OVERRIDE;
     177             : 
     178             :     // XNamespaceMapping
     179             :     virtual sal_Int32 SAL_CALL getUidByUri( OUString const & Uri )
     180             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     181             :     virtual OUString SAL_CALL getUriByUid( sal_Int32 Uid )
     182             :         throw (container::NoSuchElementException, RuntimeException, std::exception) SAL_OVERRIDE;
     183             : };
     184             : 
     185           0 : DocumentHandlerImpl::DocumentHandlerImpl(
     186             :     Reference< xml::input::XRoot > const & xRoot,
     187             :     bool bSingleThreadedUse )
     188             :     : m_xRoot( xRoot ),
     189             :       m_uid_count( 0 ),
     190             :       m_sXMLNS_PREFIX_UNKNOWN( "<<< unknown prefix >>>" ),
     191             :       m_sXMLNS( "xmlns" ),
     192             :       m_nLastURI_lookup( UID_UNKNOWN ),
     193             :       m_aLastURI_lookup( "<<< unknown URI >>>" ),
     194             :       m_nLastPrefix_lookup( UID_UNKNOWN ),
     195             :       m_aLastPrefix_lookup( "<<< unknown URI >>>" ),
     196             :       m_nSkipElements( 0 ),
     197           0 :       m_pMutex( 0 )
     198             : {
     199           0 :     m_elements.reserve( 10 );
     200             : 
     201           0 :     if (! bSingleThreadedUse)
     202           0 :         m_pMutex = new Mutex();
     203           0 : }
     204             : 
     205           0 : DocumentHandlerImpl::~DocumentHandlerImpl() throw ()
     206             : {
     207           0 :     if (m_pMutex != 0)
     208             :     {
     209           0 :         delete m_pMutex;
     210             : #if OSL_DEBUG_LEVEL == 0
     211           0 :         m_pMutex = 0;
     212             : #endif
     213             :     }
     214           0 : }
     215             : 
     216             : inline Reference< xml::input::XElement >
     217           0 : DocumentHandlerImpl::getCurrentElement() const
     218             : {
     219           0 :     MGuard aGuard( m_pMutex );
     220           0 :     if (m_elements.empty())
     221           0 :         return Reference< xml::input::XElement >();
     222             :     else
     223           0 :         return m_elements.back()->m_xElement;
     224             : }
     225             : 
     226           0 : inline sal_Int32 DocumentHandlerImpl::getUidByURI( OUString const & rURI )
     227             : {
     228           0 :     MGuard guard( m_pMutex );
     229           0 :     if (m_nLastURI_lookup == UID_UNKNOWN || m_aLastURI_lookup != rURI)
     230             :     {
     231           0 :         t_OUString2LongMap::const_iterator iFind( m_URI2Uid.find( rURI ) );
     232           0 :         if (iFind != m_URI2Uid.end()) // id found
     233             :         {
     234           0 :             m_nLastURI_lookup = iFind->second;
     235           0 :             m_aLastURI_lookup = rURI;
     236             :         }
     237             :         else
     238             :         {
     239           0 :             m_nLastURI_lookup = m_uid_count;
     240           0 :             ++m_uid_count;
     241           0 :             m_URI2Uid[ rURI ] = m_nLastURI_lookup;
     242           0 :             m_aLastURI_lookup = rURI;
     243             :         }
     244             :     }
     245           0 :     return m_nLastURI_lookup;
     246             : }
     247             : 
     248           0 : inline sal_Int32 DocumentHandlerImpl::getUidByPrefix(
     249             :     OUString const & rPrefix )
     250             : {
     251             :     // commonly the last added prefix is used often for several tags...
     252             :     // good guess
     253           0 :     if (m_nLastPrefix_lookup == UID_UNKNOWN || m_aLastPrefix_lookup != rPrefix)
     254             :     {
     255             :         t_OUString2PrefixMap::const_iterator iFind(
     256           0 :             m_prefixes.find( rPrefix ) );
     257           0 :         if (iFind != m_prefixes.end())
     258             :         {
     259           0 :             const PrefixEntry & rPrefixEntry = *iFind->second;
     260             :             SAL_WARN_IF( rPrefixEntry.m_Uids.empty(), "xmlscript.xmlhelper", "rPrefixEntry.m_Uids is empty" );
     261           0 :             m_nLastPrefix_lookup = rPrefixEntry.m_Uids.back();
     262           0 :             m_aLastPrefix_lookup = rPrefix;
     263             :         }
     264             :         else
     265             :         {
     266           0 :             m_nLastPrefix_lookup = UID_UNKNOWN;
     267           0 :             m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN;
     268             :         }
     269             :     }
     270           0 :     return m_nLastPrefix_lookup;
     271             : }
     272             : 
     273           0 : inline void DocumentHandlerImpl::pushPrefix(
     274             :     OUString const & rPrefix, OUString const & rURI )
     275             : {
     276             :     // lookup id for URI
     277           0 :     sal_Int32 nUid = getUidByURI( rURI );
     278             : 
     279             :     // mark prefix with id
     280           0 :     t_OUString2PrefixMap::const_iterator iFind( m_prefixes.find( rPrefix ) );
     281           0 :     if (iFind == m_prefixes.end()) // unused prefix
     282             :     {
     283           0 :         PrefixEntry * pEntry = new PrefixEntry();
     284           0 :         pEntry->m_Uids.push_back( nUid ); // latest id for prefix
     285           0 :         m_prefixes[ rPrefix ] = pEntry;
     286             :     }
     287             :     else
     288             :     {
     289           0 :         PrefixEntry * pEntry = iFind->second;
     290             :         SAL_WARN_IF( pEntry->m_Uids.empty(), "xmlscript.xmlhelper", "pEntry->m_Uids is empty" );
     291           0 :         pEntry->m_Uids.push_back( nUid );
     292             :     }
     293             : 
     294           0 :     m_aLastPrefix_lookup = rPrefix;
     295           0 :     m_nLastPrefix_lookup = nUid;
     296           0 : }
     297             : 
     298           0 : inline void DocumentHandlerImpl::popPrefix(
     299             :     OUString const & rPrefix )
     300             : {
     301           0 :     t_OUString2PrefixMap::iterator iFind( m_prefixes.find( rPrefix ) );
     302           0 :     if (iFind != m_prefixes.end()) // unused prefix
     303             :     {
     304           0 :         PrefixEntry * pEntry = iFind->second;
     305           0 :         pEntry->m_Uids.pop_back(); // pop last id for prefix
     306           0 :         if (pEntry->m_Uids.empty()) // erase prefix key
     307             :         {
     308           0 :             m_prefixes.erase( iFind );
     309           0 :             delete pEntry;
     310             :         }
     311             :     }
     312             : 
     313           0 :     m_nLastPrefix_lookup = UID_UNKNOWN;
     314           0 :     m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN;
     315           0 : }
     316             : 
     317           0 : inline void DocumentHandlerImpl::getElementName(
     318             :     OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName )
     319             : {
     320           0 :     sal_Int32 nColonPos = rQName.indexOf( (sal_Unicode)':' );
     321           0 :     *pLocalName = (nColonPos >= 0 ? rQName.copy( nColonPos +1 ) : rQName);
     322             :     *pUid = getUidByPrefix(
     323           0 :         nColonPos >= 0 ? rQName.copy( 0, nColonPos ) : OUString() );
     324           0 : }
     325             : 
     326             : class ExtendedAttributes :
     327             :     public ::cppu::WeakImplHelper1< xml::input::XAttributes >
     328             : {
     329             :     sal_Int32 m_nAttributes;
     330             :     sal_Int32 * m_pUids;
     331             :     OUString * m_pPrefixes;
     332             :     OUString * m_pLocalNames;
     333             :     OUString * m_pQNames;
     334             :     OUString * m_pValues;
     335             : 
     336             :     DocumentHandlerImpl * m_pHandler;
     337             : 
     338             : public:
     339             :     inline ExtendedAttributes(
     340             :         sal_Int32 nAttributes,
     341             :         sal_Int32 * pUids, OUString * pPrefixes,
     342             :         OUString * pLocalNames, OUString * pQNames,
     343             :         Reference< xml::sax::XAttributeList > const & xAttributeList,
     344             :         DocumentHandlerImpl * pHandler );
     345             :     virtual ~ExtendedAttributes() throw ();
     346             : 
     347             :     // XAttributes
     348             :     virtual sal_Int32 SAL_CALL getLength()
     349             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     350             :     virtual sal_Int32 SAL_CALL getIndexByQName(
     351             :         OUString const & rQName )
     352             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     353             :     virtual sal_Int32 SAL_CALL getIndexByUidName(
     354             :         sal_Int32 nUid, OUString const & rLocalName )
     355             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     356             :     virtual OUString SAL_CALL getQNameByIndex(
     357             :         sal_Int32 nIndex )
     358             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     359             :     virtual sal_Int32 SAL_CALL getUidByIndex(
     360             :         sal_Int32 nIndex )
     361             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     362             :     virtual OUString SAL_CALL getLocalNameByIndex(
     363             :         sal_Int32 nIndex )
     364             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     365             :     virtual OUString SAL_CALL getValueByIndex(
     366             :         sal_Int32 nIndex )
     367             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     368             :     virtual OUString SAL_CALL getValueByUidName(
     369             :         sal_Int32 nUid, OUString const & rLocalName )
     370             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     371             :     virtual OUString SAL_CALL getTypeByIndex(
     372             :         sal_Int32 nIndex )
     373             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     374             : };
     375             : 
     376           0 : inline ExtendedAttributes::ExtendedAttributes(
     377             :     sal_Int32 nAttributes,
     378             :     sal_Int32 * pUids, OUString * pPrefixes,
     379             :     OUString * pLocalNames, OUString * pQNames,
     380             :     Reference< xml::sax::XAttributeList > const & xAttributeList,
     381             :     DocumentHandlerImpl * pHandler )
     382             :     : m_nAttributes( nAttributes )
     383             :     , m_pUids( pUids )
     384             :     , m_pPrefixes( pPrefixes )
     385             :     , m_pLocalNames( pLocalNames )
     386             :     , m_pQNames( pQNames )
     387           0 :     , m_pValues( new OUString[ nAttributes ] )
     388           0 :     , m_pHandler( pHandler )
     389             : {
     390           0 :     m_pHandler->acquire();
     391             : 
     392           0 :     for ( sal_Int16 nPos = 0; nPos < nAttributes; ++nPos )
     393             :     {
     394           0 :         m_pValues[ nPos ] = xAttributeList->getValueByIndex( nPos );
     395             :     }
     396           0 : }
     397             : 
     398           0 : ExtendedAttributes::~ExtendedAttributes() throw ()
     399             : {
     400           0 :     m_pHandler->release();
     401             : 
     402           0 :     delete [] m_pUids;
     403           0 :     delete [] m_pPrefixes;
     404           0 :     delete [] m_pLocalNames;
     405           0 :     delete [] m_pQNames;
     406           0 :     delete [] m_pValues;
     407           0 : }
     408             : 
     409             : // XServiceInfo
     410             : 
     411           0 : OUString DocumentHandlerImpl::getImplementationName()
     412             :     throw (RuntimeException, std::exception)
     413             : {
     414           0 :     return getImplementationName_DocumentHandlerImpl();
     415             : }
     416             : 
     417           0 : sal_Bool DocumentHandlerImpl::supportsService( OUString const & servicename )
     418             :     throw (RuntimeException, std::exception)
     419             : {
     420           0 :     return cppu::supportsService(this, servicename);
     421             : }
     422             : 
     423           0 : Sequence< OUString > DocumentHandlerImpl::getSupportedServiceNames()
     424             :     throw (RuntimeException, std::exception)
     425             : {
     426           0 :     return getSupportedServiceNames_DocumentHandlerImpl();
     427             : }
     428             : 
     429             : // XInitialization
     430             : 
     431           0 : void DocumentHandlerImpl::initialize(
     432             :     Sequence< Any > const & arguments )
     433             :     throw (Exception, std::exception)
     434             : {
     435           0 :     MGuard guard( m_pMutex );
     436           0 :     Reference< xml::input::XRoot > xRoot;
     437           0 :     if (arguments.getLength() == 1 &&
     438           0 :         (arguments[ 0 ] >>= xRoot) &&
     439           0 :         xRoot.is())
     440             :     {
     441           0 :         m_xRoot = xRoot;
     442             :     }
     443             :     else
     444             :     {
     445           0 :         throw RuntimeException( "missing root instance!", Reference< XInterface >() );
     446           0 :     }
     447           0 : }
     448             : 
     449             : // XNamespaceMapping
     450             : 
     451           0 : sal_Int32 DocumentHandlerImpl::getUidByUri( OUString const & Uri )
     452             :     throw (RuntimeException, std::exception)
     453             : {
     454           0 :     sal_Int32 uid = getUidByURI( Uri );
     455             :     SAL_WARN_IF( uid == UID_UNKNOWN, "xmlscript.xmlhelper", "uid UNKNOWN");
     456           0 :     return uid;
     457             : }
     458             : 
     459           0 : OUString DocumentHandlerImpl::getUriByUid( sal_Int32 Uid )
     460             :     throw (container::NoSuchElementException, RuntimeException, std::exception)
     461             : {
     462           0 :     MGuard guard( m_pMutex );
     463           0 :     t_OUString2LongMap::const_iterator iPos( m_URI2Uid.begin() );
     464           0 :     t_OUString2LongMap::const_iterator const iEnd( m_URI2Uid.end() );
     465           0 :     for ( ; iPos != iEnd; ++iPos )
     466             :     {
     467           0 :         if (iPos->second == Uid)
     468           0 :             return iPos->first;
     469             :     }
     470           0 :     throw container::NoSuchElementException( "no such xmlns uid!" , static_cast< OWeakObject * >(this) );
     471             : }
     472             : 
     473             : // XDocumentHandler
     474             : 
     475           0 : void DocumentHandlerImpl::startDocument()
     476             :     throw (xml::sax::SAXException, RuntimeException, std::exception)
     477             : {
     478           0 :     m_xRoot->startDocument( static_cast< xml::input::XNamespaceMapping * >( this ) );
     479           0 : }
     480             : 
     481           0 : void DocumentHandlerImpl::endDocument()
     482             :     throw (xml::sax::SAXException, RuntimeException, std::exception)
     483             : {
     484           0 :     m_xRoot->endDocument();
     485           0 : }
     486             : 
     487           0 : void DocumentHandlerImpl::startElement(
     488             :     OUString const & rQElementName,
     489             :     Reference< xml::sax::XAttributeList > const & xAttribs )
     490             :     throw (xml::sax::SAXException, RuntimeException, std::exception)
     491             : {
     492           0 :     Reference< xml::input::XElement > xCurrentElement;
     493           0 :     Reference< xml::input::XAttributes > xAttributes;
     494             :     sal_Int32 nUid;
     495           0 :     OUString aLocalName;
     496           0 :     ::std::auto_ptr< ElementEntry > elementEntry( new ElementEntry );
     497             : 
     498             :     { // guard start:
     499           0 :     MGuard aGuard( m_pMutex );
     500             :     // currently skipping elements and waiting for end tags?
     501           0 :     if (m_nSkipElements > 0)
     502             :     {
     503           0 :         ++m_nSkipElements; // wait for another end tag
     504             : #if OSL_DEBUG_LEVEL > 1
     505             :         OString aQName(
     506             :             OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
     507             :         SAL_INFO("xmlscript.xmlhelper", "### no context given on createChildElement() => ignoring element \"" << aQName.getStr() << "\" ...");
     508             : #endif
     509           0 :         return;
     510             :     }
     511             : 
     512           0 :     sal_Int16 nAttribs = xAttribs->getLength();
     513             : 
     514             :     // save all namespace ids
     515           0 :     sal_Int32 * pUids = new sal_Int32[ nAttribs ];
     516           0 :     OUString * pPrefixes = new OUString[ nAttribs ];
     517           0 :     OUString * pLocalNames = new OUString[ nAttribs ];
     518           0 :     OUString * pQNames = new OUString[ nAttribs ];
     519             : 
     520             :     // first recognize all xmlns attributes
     521             :     sal_Int16 nPos;
     522           0 :     for ( nPos = 0; nPos < nAttribs; ++nPos )
     523             :     {
     524             :         // mark attribute to be collected further
     525             :         // on with attribute's uid and current prefix
     526           0 :         pUids[ nPos ] = 0; // modified
     527             : 
     528           0 :         pQNames[ nPos ] = xAttribs->getNameByIndex( nPos );
     529           0 :         OUString const & rQAttributeName = pQNames[ nPos ];
     530             : 
     531           0 :         if (rQAttributeName.startsWith( m_sXMLNS ))
     532             :         {
     533           0 :             if (rQAttributeName.getLength() == 5) // set default namespace
     534             :             {
     535           0 :                 OUString aDefNamespacePrefix;
     536             :                 pushPrefix(
     537             :                     aDefNamespacePrefix,
     538           0 :                     xAttribs->getValueByIndex( nPos ) );
     539           0 :                 elementEntry->m_prefixes.push_back( aDefNamespacePrefix );
     540           0 :                 pUids[ nPos ]          = UID_UNKNOWN;
     541           0 :                 pPrefixes[ nPos ]      = m_sXMLNS;
     542           0 :                 pLocalNames[ nPos ]    = aDefNamespacePrefix;
     543             :             }
     544           0 :             else if ((sal_Unicode)':' == rQAttributeName[ 5 ]) // set prefix
     545             :             {
     546           0 :                 OUString aPrefix( rQAttributeName.copy( 6 ) );
     547           0 :                 pushPrefix( aPrefix, xAttribs->getValueByIndex( nPos ) );
     548           0 :                 elementEntry->m_prefixes.push_back( aPrefix );
     549           0 :                 pUids[ nPos ]          = UID_UNKNOWN;
     550           0 :                 pPrefixes[ nPos ]      = m_sXMLNS;
     551           0 :                 pLocalNames[ nPos ]    = aPrefix;
     552             :             }
     553             :             // else just a name starting with xmlns, but no prefix
     554             :         }
     555             :     }
     556             : 
     557             :     // now read out attribute prefixes (all namespace prefixes have been set)
     558           0 :     for ( nPos = 0; nPos < nAttribs; ++nPos )
     559             :     {
     560           0 :         if (pUids[ nPos ] >= 0) // no xmlns: attribute
     561             :         {
     562           0 :             OUString const & rQAttributeName = pQNames[ nPos ];
     563             :             SAL_WARN_IF(rQAttributeName.startsWith( "xmlns:" ), "xmlscript.xmlhelper", "### unexpected xmlns!" );
     564             : 
     565             :             // collect attribute's uid and current prefix
     566           0 :             sal_Int32 nColonPos = rQAttributeName.indexOf( (sal_Unicode) ':' );
     567           0 :             if (nColonPos >= 0)
     568             :             {
     569           0 :                 pPrefixes[ nPos ] = rQAttributeName.copy( 0, nColonPos );
     570           0 :                 pLocalNames[ nPos ] = rQAttributeName.copy( nColonPos +1 );
     571             :             }
     572             :             else
     573             :             {
     574           0 :                 pPrefixes[ nPos ] = OUString();
     575           0 :                 pLocalNames[ nPos ] = rQAttributeName;
     576             :                 // leave local names unmodified
     577             :             }
     578           0 :             pUids[ nPos ] = getUidByPrefix( pPrefixes[ nPos ] );
     579             :         }
     580             :     }
     581             :     // ownership of arrays belongs to attribute list
     582             :     xAttributes = static_cast< xml::input::XAttributes * >(
     583             :         new ExtendedAttributes(
     584             :             nAttribs, pUids, pPrefixes, pLocalNames, pQNames,
     585           0 :             xAttribs, this ) );
     586             : 
     587           0 :     getElementName( rQElementName, &nUid, &aLocalName );
     588             : 
     589             :     // create new child context and append to list
     590           0 :     if (! m_elements.empty())
     591           0 :         xCurrentElement = m_elements.back()->m_xElement;
     592             :     } // :guard end
     593             : 
     594           0 :     if (xCurrentElement.is())
     595             :     {
     596           0 :         elementEntry->m_xElement =
     597           0 :             xCurrentElement->startChildElement( nUid, aLocalName, xAttributes );
     598             :     }
     599             :     else
     600             :     {
     601           0 :         elementEntry->m_xElement =
     602           0 :             m_xRoot->startRootElement( nUid, aLocalName, xAttributes );
     603             :     }
     604             : 
     605             :     {
     606           0 :     MGuard aGuard( m_pMutex );
     607           0 :     if (elementEntry->m_xElement.is())
     608             :     {
     609           0 :         m_elements.push_back( elementEntry.release() );
     610             :     }
     611             :     else
     612             :     {
     613           0 :         ++m_nSkipElements;
     614             : #if OSL_DEBUG_LEVEL > 1
     615             :         OString aQName(
     616             :             OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
     617             :         SAL_INFO("xmlscript.xmlhelper", "### no context given on createChildElement() => ignoring element \"" << aQName.getStr() << "\" ...");
     618             : #endif
     619           0 :     }
     620           0 :     }
     621             : }
     622             : 
     623           0 : void DocumentHandlerImpl::endElement(
     624             :     OUString const & rQElementName )
     625             :     throw (xml::sax::SAXException, RuntimeException, std::exception)
     626             : {
     627           0 :     Reference< xml::input::XElement > xCurrentElement;
     628             :     {
     629           0 :     MGuard aGuard( m_pMutex );
     630           0 :     if (m_nSkipElements)
     631             :     {
     632           0 :         --m_nSkipElements;
     633             : #if OSL_DEBUG_LEVEL > 1
     634             :         OString aQName(
     635             :             OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) );
     636             :         SAL_INFO("xmlscript.xmlhelper", "### received endElement() for \"" << aQName.getStr() << "\".");
     637             : #endif
     638             :         static_cast<void>(rQElementName);
     639           0 :         return;
     640             :     }
     641             : 
     642             :     // popping context
     643             :     SAL_WARN_IF( m_elements.empty(), "xmlscript.xmlhelper", "m_elements is empty" );
     644           0 :     ElementEntry * pEntry = m_elements.back();
     645           0 :     xCurrentElement = pEntry->m_xElement;
     646             : 
     647             : #if OSL_DEBUG_LEVEL > 0
     648             :     sal_Int32 nUid;
     649             :     OUString aLocalName;
     650             :     getElementName( rQElementName, &nUid, &aLocalName );
     651             :     SAL_WARN_IF( xCurrentElement->getLocalName() != aLocalName, "xmlscript.xmlhelper", "xCurrentElement->getLocalName() != aLocalName" );
     652             :     SAL_WARN_IF( xCurrentElement->getUid() != nUid, "xmlscript.xmlhelper", "xCurrentElement->getUid() != nUid" );
     653             : #endif
     654             : 
     655             :     // pop prefixes
     656           0 :     for ( sal_Int32 nPos = pEntry->m_prefixes.size(); nPos--; )
     657             :     {
     658           0 :         popPrefix( pEntry->m_prefixes[ nPos ] );
     659             :     }
     660           0 :     m_elements.pop_back();
     661           0 :     delete pEntry;
     662             :     }
     663           0 :     xCurrentElement->endElement();
     664             : }
     665             : 
     666           0 : void DocumentHandlerImpl::characters( OUString const & rChars )
     667             :     throw (xml::sax::SAXException, RuntimeException, std::exception)
     668             : {
     669           0 :     Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
     670           0 :     if (xCurrentElement.is())
     671           0 :         xCurrentElement->characters( rChars );
     672           0 : }
     673             : 
     674           0 : void DocumentHandlerImpl::ignorableWhitespace(
     675             :     OUString const & rWhitespaces )
     676             :     throw (xml::sax::SAXException, RuntimeException, std::exception)
     677             : {
     678           0 :     Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
     679           0 :     if (xCurrentElement.is())
     680           0 :         xCurrentElement->ignorableWhitespace( rWhitespaces );
     681           0 : }
     682             : 
     683           0 : void DocumentHandlerImpl::processingInstruction(
     684             :     OUString const & rTarget, OUString const & rData )
     685             :     throw (xml::sax::SAXException, RuntimeException, std::exception)
     686             : {
     687           0 :     Reference< xml::input::XElement > xCurrentElement( getCurrentElement() );
     688           0 :     if (xCurrentElement.is())
     689           0 :         xCurrentElement->processingInstruction( rTarget, rData );
     690             :     else
     691           0 :         m_xRoot->processingInstruction( rTarget, rData );
     692           0 : }
     693             : 
     694           0 : void DocumentHandlerImpl::setDocumentLocator(
     695             :     Reference< xml::sax::XLocator > const & xLocator )
     696             :     throw (xml::sax::SAXException, RuntimeException, std::exception)
     697             : {
     698           0 :     m_xRoot->setDocumentLocator( xLocator );
     699           0 : }
     700             : 
     701             : // XAttributes
     702             : 
     703           0 : sal_Int32 ExtendedAttributes::getIndexByQName( OUString const & rQName )
     704             :     throw (RuntimeException, std::exception)
     705             : {
     706           0 :     for ( sal_Int32 nPos = m_nAttributes; nPos--; )
     707             :     {
     708           0 :         if (m_pQNames[ nPos ].equals( rQName ))
     709             :         {
     710           0 :             return nPos;
     711             :         }
     712             :     }
     713           0 :     return -1;
     714             : }
     715             : 
     716           0 : sal_Int32 ExtendedAttributes::getLength()
     717             :     throw (RuntimeException, std::exception)
     718             : {
     719           0 :     return m_nAttributes;
     720             : }
     721             : 
     722           0 : OUString ExtendedAttributes::getLocalNameByIndex( sal_Int32 nIndex )
     723             :     throw (RuntimeException, std::exception)
     724             : {
     725           0 :     if (nIndex < m_nAttributes)
     726           0 :         return m_pLocalNames[ nIndex ];
     727             :     else
     728           0 :         return OUString();
     729             : }
     730             : 
     731           0 : OUString ExtendedAttributes::getQNameByIndex( sal_Int32 nIndex )
     732             :     throw (RuntimeException, std::exception)
     733             : {
     734           0 :     if (nIndex < m_nAttributes)
     735           0 :         return m_pQNames[ nIndex ];
     736             :     else
     737           0 :         return OUString();
     738             : }
     739             : 
     740           0 : OUString ExtendedAttributes::getTypeByIndex( sal_Int32 nIndex )
     741             :     throw (RuntimeException, std::exception)
     742             : {
     743             :     static_cast<void>(nIndex);
     744             :     SAL_WARN_IF( nIndex >= m_nAttributes , "xmlscript.xmlhelper", "nIndex is bigger then m_nAttributes");
     745           0 :     return OUString(); // unsupported
     746             : }
     747             : 
     748           0 : OUString ExtendedAttributes::getValueByIndex( sal_Int32 nIndex )
     749             :     throw (RuntimeException, std::exception)
     750             : {
     751           0 :     if (nIndex < m_nAttributes)
     752           0 :         return m_pValues[ nIndex ];
     753             :     else
     754           0 :         return OUString();
     755             : }
     756             : 
     757           0 : sal_Int32 ExtendedAttributes::getIndexByUidName(
     758             :     sal_Int32 nUid, OUString const & rLocalName )
     759             :     throw (RuntimeException, std::exception)
     760             : {
     761           0 :     for ( sal_Int32 nPos = m_nAttributes; nPos--; )
     762             :     {
     763           0 :         if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName)
     764             :         {
     765           0 :             return nPos;
     766             :         }
     767             :     }
     768           0 :     return -1;
     769             : }
     770             : 
     771           0 : sal_Int32 ExtendedAttributes::getUidByIndex( sal_Int32 nIndex )
     772             :     throw (RuntimeException, std::exception)
     773             : {
     774           0 :     if (nIndex < m_nAttributes)
     775           0 :         return m_pUids[ nIndex ];
     776             :     else
     777           0 :         return -1;
     778             : }
     779             : 
     780           0 : OUString ExtendedAttributes::getValueByUidName(
     781             :     sal_Int32 nUid, OUString const & rLocalName )
     782             :     throw (RuntimeException, std::exception)
     783             : {
     784           0 :     for ( sal_Int32 nPos = m_nAttributes; nPos--; )
     785             :     {
     786           0 :         if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName)
     787             :         {
     788           0 :             return m_pValues[ nPos ];
     789             :         }
     790             :     }
     791           0 :     return OUString();
     792             : }
     793             : 
     794           0 : Reference< xml::sax::XDocumentHandler > SAL_CALL createDocumentHandler(
     795             :     Reference< xml::input::XRoot > const & xRoot,
     796             :     bool bSingleThreadedUse )
     797             :     SAL_THROW(())
     798             : {
     799             :     SAL_WARN_IF( !xRoot.is(), "xmlscript.xmlhelper", "xRoot is NULL" );
     800           0 :     if (xRoot.is())
     801             :     {
     802             :         return static_cast< xml::sax::XDocumentHandler * >(
     803           0 :             new DocumentHandlerImpl( xRoot, bSingleThreadedUse ) );
     804             :     }
     805           0 :     return Reference< xml::sax::XDocumentHandler >();
     806             : }
     807             : 
     808           0 : Reference< XInterface > SAL_CALL create_DocumentHandlerImpl(
     809             :     SAL_UNUSED_PARAMETER Reference< XComponentContext > const & )
     810             :     SAL_THROW( (Exception) )
     811             : {
     812             :     return static_cast< ::cppu::OWeakObject * >(
     813             :         new DocumentHandlerImpl(
     814           0 :             Reference< xml::input::XRoot >(), false /* mt use */ ) );
     815             : }
     816             : 
     817             : }
     818             : 
     819             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10