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

Generated by: LCOV version 1.10