/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmlscript.hxx" #include "osl/diagnose.h" #include "osl/mutex.hxx" #include "rtl/ustrbuf.hxx" #include "cppuhelper/factory.hxx" #include "cppuhelper/implementationentry.hxx" #include "cppuhelper/implbase1.hxx" #include "cppuhelper/implbase3.hxx" #include "xml_import.hxx" #include "com/sun/star/xml/input/XAttributes.hpp" #include "com/sun/star/lang/XInitialization.hpp" #include "com/sun/star/uno/XComponentContext.hpp" #include #include #include using namespace ::rtl; using namespace ::osl; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; namespace xmlscript { const sal_Int32 UID_UNKNOWN = -1; Sequence< OUString > getSupportedServiceNames_DocumentHandlerImpl() { OUString name( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.input.SaxDocumentHandler") ); return Sequence< OUString >( &name, 1 ); } OUString getImplementationName_DocumentHandlerImpl() { return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.xml.input.SaxDocumentHandler") ); } typedef ::std::hash_map< OUString, sal_Int32, OUStringHash > t_OUString2LongMap; typedef ::std::hash_map< sal_Int32, OUString > t_Long2OUStringMap; struct PrefixEntry { ::std::vector< sal_Int32 > m_Uids; inline PrefixEntry() SAL_THROW( () ) { m_Uids.reserve( 4 ); } }; typedef ::std::hash_map< OUString, PrefixEntry *, OUStringHash > t_OUString2PrefixMap; struct ElementEntry { Reference< xml::input::XElement > m_xElement; ::std::vector< OUString > m_prefixes; inline ElementEntry() { m_prefixes.reserve( 2 ); } }; typedef ::std::vector< ElementEntry * > t_ElementVector; class ExtendedAttributes; //============================================================================== struct MGuard { Mutex * m_pMutex; explicit MGuard( Mutex * pMutex ) : m_pMutex( pMutex ) { if (m_pMutex) m_pMutex->acquire(); } ~MGuard() throw () { if (m_pMutex) m_pMutex->release(); } }; //============================================================================== class DocumentHandlerImpl : public ::cppu::WeakImplHelper3< xml::sax::XDocumentHandler, xml::input::XNamespaceMapping, lang::XInitialization > { friend class ExtendedAttributes; Reference< xml::input::XRoot > m_xRoot; t_OUString2LongMap m_URI2Uid; sal_Int32 m_uid_count; OUString m_sXMLNS_PREFIX_UNKNOWN; OUString m_sXMLNS; sal_Int32 m_nLastURI_lookup; OUString m_aLastURI_lookup; t_OUString2PrefixMap m_prefixes; sal_Int32 m_nLastPrefix_lookup; OUString m_aLastPrefix_lookup; t_ElementVector m_elements; sal_Int32 m_nSkipElements; Mutex * m_pMutex; inline Reference< xml::input::XElement > getCurrentElement() const; inline sal_Int32 getUidByURI( OUString const & rURI ); inline sal_Int32 getUidByPrefix( OUString const & rPrefix ); inline void pushPrefix( OUString const & rPrefix, OUString const & rURI ); inline void popPrefix( OUString const & rPrefix ); inline void getElementName( OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName ); public: DocumentHandlerImpl( Reference< xml::input::XRoot > const & xRoot, bool bSingleThreadedUse ); virtual ~DocumentHandlerImpl() throw (); // XServiceInfo virtual OUString SAL_CALL getImplementationName() throw (RuntimeException); virtual sal_Bool SAL_CALL supportsService( OUString const & servicename ) throw (RuntimeException); virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException); // XInitialization virtual void SAL_CALL initialize( Sequence< Any > const & arguments ) throw (Exception); // XDocumentHandler virtual void SAL_CALL startDocument() throw (xml::sax::SAXException, RuntimeException); virtual void SAL_CALL endDocument() throw (xml::sax::SAXException, RuntimeException); virtual void SAL_CALL startElement( OUString const & rQElementName, Reference< xml::sax::XAttributeList > const & xAttribs ) throw (xml::sax::SAXException, RuntimeException); virtual void SAL_CALL endElement( OUString const & rQElementName ) throw (xml::sax::SAXException, RuntimeException); virtual void SAL_CALL characters( OUString const & rChars ) throw (xml::sax::SAXException, RuntimeException); virtual void SAL_CALL ignorableWhitespace( OUString const & rWhitespaces ) throw (xml::sax::SAXException, RuntimeException); virtual void SAL_CALL processingInstruction( OUString const & rTarget, OUString const & rData ) throw (xml::sax::SAXException, RuntimeException); virtual void SAL_CALL setDocumentLocator( Reference< xml::sax::XLocator > const & xLocator ) throw (xml::sax::SAXException, RuntimeException); // XNamespaceMapping virtual sal_Int32 SAL_CALL getUidByUri( OUString const & Uri ) throw (RuntimeException); virtual OUString SAL_CALL getUriByUid( sal_Int32 Uid ) throw (container::NoSuchElementException, RuntimeException); }; //______________________________________________________________________________ DocumentHandlerImpl::DocumentHandlerImpl( Reference< xml::input::XRoot > const & xRoot, bool bSingleThreadedUse ) : m_xRoot( xRoot ), m_uid_count( 0 ), m_sXMLNS_PREFIX_UNKNOWN( RTL_CONSTASCII_USTRINGPARAM("<<< unknown prefix >>>") ), m_sXMLNS( RTL_CONSTASCII_USTRINGPARAM("xmlns") ), m_nLastURI_lookup( UID_UNKNOWN ), m_aLastURI_lookup( RTL_CONSTASCII_USTRINGPARAM("<<< unknown URI >>>") ), m_nLastPrefix_lookup( UID_UNKNOWN ), m_aLastPrefix_lookup( RTL_CONSTASCII_USTRINGPARAM("<<< unknown URI >>>") ), m_nSkipElements( 0 ), m_pMutex( 0 ) { m_elements.reserve( 10 ); if (! bSingleThreadedUse) m_pMutex = new Mutex(); } //______________________________________________________________________________ DocumentHandlerImpl::~DocumentHandlerImpl() throw () { if (m_pMutex != 0) { delete m_pMutex; #if OSL_DEBUG_LEVEL == 0 m_pMutex = 0; #endif } } //______________________________________________________________________________ inline Reference< xml::input::XElement > DocumentHandlerImpl::getCurrentElement() const { MGuard aGuard( m_pMutex ); if (m_elements.empty()) return Reference< xml::input::XElement >(); else return m_elements.back()->m_xElement; } //______________________________________________________________________________ inline sal_Int32 DocumentHandlerImpl::getUidByURI( OUString const & rURI ) { MGuard guard( m_pMutex ); if (m_nLastURI_lookup == UID_UNKNOWN || m_aLastURI_lookup != rURI) { t_OUString2LongMap::const_iterator iFind( m_URI2Uid.find( rURI ) ); if (iFind != m_URI2Uid.end()) // id found { m_nLastURI_lookup = iFind->second; m_aLastURI_lookup = rURI; } else { m_nLastURI_lookup = m_uid_count; ++m_uid_count; m_URI2Uid[ rURI ] = m_nLastURI_lookup; m_aLastURI_lookup = rURI; } } return m_nLastURI_lookup; } //______________________________________________________________________________ inline sal_Int32 DocumentHandlerImpl::getUidByPrefix( OUString const & rPrefix ) { // commonly the last added prefix is used often for several tags... // good guess if (m_nLastPrefix_lookup == UID_UNKNOWN || m_aLastPrefix_lookup != rPrefix) { t_OUString2PrefixMap::const_iterator iFind( m_prefixes.find( rPrefix ) ); if (iFind != m_prefixes.end()) { const PrefixEntry & rPrefixEntry = *iFind->second; OSL_ASSERT( ! rPrefixEntry.m_Uids.empty() ); m_nLastPrefix_lookup = rPrefixEntry.m_Uids.back(); m_aLastPrefix_lookup = rPrefix; } else { m_nLastPrefix_lookup = UID_UNKNOWN; m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN; } } return m_nLastPrefix_lookup; } //______________________________________________________________________________ inline void DocumentHandlerImpl::pushPrefix( OUString const & rPrefix, OUString const & rURI ) { // lookup id for URI sal_Int32 nUid = getUidByURI( rURI ); // mark prefix with id t_OUString2PrefixMap::const_iterator iFind( m_prefixes.find( rPrefix ) ); if (iFind == m_prefixes.end()) // unused prefix { PrefixEntry * pEntry = new PrefixEntry(); pEntry->m_Uids.push_back( nUid ); // latest id for prefix m_prefixes[ rPrefix ] = pEntry; } else { PrefixEntry * pEntry = iFind->second; OSL_ASSERT( ! pEntry->m_Uids.empty() ); pEntry->m_Uids.push_back( nUid ); } m_aLastPrefix_lookup = rPrefix; m_nLastPrefix_lookup = nUid; } //______________________________________________________________________________ inline void DocumentHandlerImpl::popPrefix( OUString const & rPrefix ) { t_OUString2PrefixMap::iterator iFind( m_prefixes.find( rPrefix ) ); if (iFind != m_prefixes.end()) // unused prefix { PrefixEntry * pEntry = iFind->second; pEntry->m_Uids.pop_back(); // pop last id for prefix if (pEntry->m_Uids.empty()) // erase prefix key { m_prefixes.erase( iFind ); delete pEntry; } } m_nLastPrefix_lookup = UID_UNKNOWN; m_aLastPrefix_lookup = m_sXMLNS_PREFIX_UNKNOWN; } //______________________________________________________________________________ inline void DocumentHandlerImpl::getElementName( OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName ) { sal_Int32 nColonPos = rQName.indexOf( (sal_Unicode)':' ); *pLocalName = (nColonPos >= 0 ? rQName.copy( nColonPos +1 ) : rQName); *pUid = getUidByPrefix( nColonPos >= 0 ? rQName.copy( 0, nColonPos ) : OUString() ); } //============================================================================== class ExtendedAttributes : public ::cppu::WeakImplHelper1< xml::input::XAttributes > { sal_Int32 m_nAttributes; sal_Int32 * m_pUids; OUString * m_pPrefixes; OUString * m_pLocalNames; OUString * m_pQNames; OUString * m_pValues; DocumentHandlerImpl * m_pHandler; public: inline ExtendedAttributes( sal_Int32 nAttributes, sal_Int32 * pUids, OUString * pPrefixes, OUString * pLocalNames, OUString * pQNames, Reference< xml::sax::XAttributeList > const & xAttributeList, DocumentHandlerImpl * pHandler ); virtual ~ExtendedAttributes() throw (); // XAttributes virtual sal_Int32 SAL_CALL getLength() throw (RuntimeException); virtual sal_Int32 SAL_CALL getIndexByQName( OUString const & rQName ) throw (RuntimeException); virtual sal_Int32 SAL_CALL getIndexByUidName( sal_Int32 nUid, OUString const & rLocalName ) throw (RuntimeException); virtual OUString SAL_CALL getQNameByIndex( sal_Int32 nIndex ) throw (RuntimeException); virtual sal_Int32 SAL_CALL getUidByIndex( sal_Int32 nIndex ) throw (RuntimeException); virtual OUString SAL_CALL getLocalNameByIndex( sal_Int32 nIndex ) throw (RuntimeException); virtual OUString SAL_CALL getValueByIndex( sal_Int32 nIndex ) throw (RuntimeException); virtual OUString SAL_CALL getValueByUidName( sal_Int32 nUid, OUString const & rLocalName ) throw (RuntimeException); virtual OUString SAL_CALL getTypeByIndex( sal_Int32 nIndex ) throw (RuntimeException); }; //______________________________________________________________________________ inline ExtendedAttributes::ExtendedAttributes( sal_Int32 nAttributes, sal_Int32 * pUids, OUString * pPrefixes, OUString * pLocalNames, OUString * pQNames, Reference< xml::sax::XAttributeList > const & xAttributeList, DocumentHandlerImpl * pHandler ) : m_nAttributes( nAttributes ) , m_pUids( pUids ) , m_pPrefixes( pPrefixes ) , m_pLocalNames( pLocalNames ) , m_pQNames( pQNames ) , m_pValues( new OUString[ nAttributes ] ) , m_pHandler( pHandler ) { m_pHandler->acquire(); for ( sal_Int16 nPos = 0; nPos < nAttributes; ++nPos ) { m_pValues[ nPos ] = xAttributeList->getValueByIndex( nPos ); } } //______________________________________________________________________________ ExtendedAttributes::~ExtendedAttributes() throw () { m_pHandler->release(); delete [] m_pUids; delete [] m_pPrefixes; delete [] m_pLocalNames; delete [] m_pQNames; delete [] m_pValues; } //############################################################################## // XServiceInfo //______________________________________________________________________________ OUString DocumentHandlerImpl::getImplementationName() throw (RuntimeException) { return getImplementationName_DocumentHandlerImpl(); } //______________________________________________________________________________ sal_Bool DocumentHandlerImpl::supportsService( OUString const & servicename ) throw (RuntimeException) { Sequence< OUString > names( getSupportedServiceNames_DocumentHandlerImpl() ); for ( sal_Int32 nPos = names.getLength(); nPos--; ) { if (names[ nPos ].equals( servicename )) return sal_True; } return sal_False; } //______________________________________________________________________________ Sequence< OUString > DocumentHandlerImpl::getSupportedServiceNames() throw (RuntimeException) { return getSupportedServiceNames_DocumentHandlerImpl(); } // XInitialization //______________________________________________________________________________ void DocumentHandlerImpl::initialize( Sequence< Any > const & arguments ) throw (Exception) { MGuard guard( m_pMutex ); Reference< xml::input::XRoot > xRoot; if (arguments.getLength() == 1 && (arguments[ 0 ] >>= xRoot) && xRoot.is()) { m_xRoot = xRoot; } else { throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( "missing root instance!") ), Reference< XInterface >() ); } } // XNamespaceMapping //______________________________________________________________________________ sal_Int32 DocumentHandlerImpl::getUidByUri( OUString const & Uri ) throw (RuntimeException) { sal_Int32 uid = getUidByURI( Uri ); OSL_ASSERT( uid != UID_UNKNOWN ); return uid; } //______________________________________________________________________________ OUString DocumentHandlerImpl::getUriByUid( sal_Int32 Uid ) throw (container::NoSuchElementException, RuntimeException) { MGuard guard( m_pMutex ); t_OUString2LongMap::const_iterator iPos( m_URI2Uid.begin() ); t_OUString2LongMap::const_iterator const iEnd( m_URI2Uid.end() ); for ( ; iPos != iEnd; ++iPos ) { if (iPos->second == Uid) return iPos->first; } throw container::NoSuchElementException( OUString( RTL_CONSTASCII_USTRINGPARAM("no such xmlns uid!") ), static_cast< OWeakObject * >(this) ); } // XDocumentHandler //______________________________________________________________________________ void DocumentHandlerImpl::startDocument() throw (xml::sax::SAXException, RuntimeException) { m_xRoot->startDocument( static_cast< xml::input::XNamespaceMapping * >( this ) ); } //______________________________________________________________________________ void DocumentHandlerImpl::endDocument() throw (xml::sax::SAXException, RuntimeException) { m_xRoot->endDocument(); } //______________________________________________________________________________ void DocumentHandlerImpl::startElement( OUString const & rQElementName, Reference< xml::sax::XAttributeList > const & xAttribs ) throw (xml::sax::SAXException, RuntimeException) { Reference< xml::input::XElement > xCurrentElement; Reference< xml::input::XAttributes > xAttributes; sal_Int32 nUid; OUString aLocalName; ::std::auto_ptr< ElementEntry > elementEntry( new ElementEntry ); { // guard start: MGuard aGuard( m_pMutex ); // currently skipping elements and waiting for end tags? if (m_nSkipElements > 0) { ++m_nSkipElements; // wait for another end tag #if OSL_DEBUG_LEVEL > 1 OString aQName( OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) ); OSL_TRACE( "### no context given on createChildElement() " "=> ignoring element \"%s\" ...", aQName.getStr() ); #endif return; } sal_Int16 nAttribs = xAttribs->getLength(); // save all namespace ids sal_Int32 * pUids = new sal_Int32[ nAttribs ]; OUString * pPrefixes = new OUString[ nAttribs ]; OUString * pLocalNames = new OUString[ nAttribs ]; OUString * pQNames = new OUString[ nAttribs ]; // first recognize all xmlns attributes sal_Int16 nPos; for ( nPos = 0; nPos < nAttribs; ++nPos ) { // mark attribute to be collected further // on with attribute's uid and current prefix pUids[ nPos ] = 0; // modified pQNames[ nPos ] = xAttribs->getNameByIndex( nPos ); OUString const & rQAttributeName = pQNames[ nPos ]; if (rQAttributeName.compareTo( m_sXMLNS, 5 ) == 0) { if (rQAttributeName.getLength() == 5) // set default namespace { OUString aDefNamespacePrefix; pushPrefix( aDefNamespacePrefix, xAttribs->getValueByIndex( nPos ) ); elementEntry->m_prefixes.push_back( aDefNamespacePrefix ); pUids[ nPos ] = UID_UNKNOWN; pPrefixes[ nPos ] = m_sXMLNS; pLocalNames[ nPos ] = aDefNamespacePrefix; } else if ((sal_Unicode)':' == rQAttributeName[ 5 ]) // set prefix { OUString aPrefix( rQAttributeName.copy( 6 ) ); pushPrefix( aPrefix, xAttribs->getValueByIndex( nPos ) ); elementEntry->m_prefixes.push_back( aPrefix ); pUids[ nPos ] = UID_UNKNOWN; pPrefixes[ nPos ] = m_sXMLNS; pLocalNames[ nPos ] = aPrefix; } // else just a name starting with xmlns, but no prefix } } // now read out attribute prefixes (all namespace prefixes have been set) for ( nPos = 0; nPos < nAttribs; ++nPos ) { if (pUids[ nPos ] >= 0) // no xmlns: attribute { OUString const & rQAttributeName = pQNames[ nPos ]; OSL_ENSURE( rQAttributeName.compareToAscii( RTL_CONSTASCII_STRINGPARAM("xmlns:") ) != 0, "### unexpected xmlns!" ); // collect attribute's uid and current prefix sal_Int32 nColonPos = rQAttributeName.indexOf( (sal_Unicode) ':' ); if (nColonPos >= 0) { pPrefixes[ nPos ] = rQAttributeName.copy( 0, nColonPos ); pLocalNames[ nPos ] = rQAttributeName.copy( nColonPos +1 ); } else { pPrefixes[ nPos ] = OUString(); pLocalNames[ nPos ] = rQAttributeName; // leave local names unmodified } pUids[ nPos ] = getUidByPrefix( pPrefixes[ nPos ] ); } } // ownership of arrays belongs to attribute list xAttributes = static_cast< xml::input::XAttributes * >( new ExtendedAttributes( nAttribs, pUids, pPrefixes, pLocalNames, pQNames, xAttribs, this ) ); getElementName( rQElementName, &nUid, &aLocalName ); // create new child context and append to list if (! m_elements.empty()) xCurrentElement = m_elements.back()->m_xElement; } // :guard end if (xCurrentElement.is()) { elementEntry->m_xElement = xCurrentElement->startChildElement( nUid, aLocalName, xAttributes ); } else { elementEntry->m_xElement = m_xRoot->startRootElement( nUid, aLocalName, xAttributes ); } { MGuard aGuard( m_pMutex ); if (elementEntry->m_xElement.is()) { m_elements.push_back( elementEntry.release() ); } else { ++m_nSkipElements; #if OSL_DEBUG_LEVEL > 1 OString aQName( OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) ); OSL_TRACE( "### no context given on createChildElement() => " "ignoring element \"%s\" ...", aQName.getStr() ); #endif } } } //______________________________________________________________________________ void DocumentHandlerImpl::endElement( OUString const & rQElementName ) throw (xml::sax::SAXException, RuntimeException) { Reference< xml::input::XElement > xCurrentElement; { MGuard aGuard( m_pMutex ); if (m_nSkipElements) { --m_nSkipElements; #if OSL_DEBUG_LEVEL > 1 OString aQName( OUStringToOString( rQElementName, RTL_TEXTENCODING_ASCII_US ) ); OSL_TRACE( "### received endElement() for \"%s\".", aQName.getStr() ); #endif static_cast(rQElementName); return; } // popping context OSL_ASSERT( ! m_elements.empty() ); ElementEntry * pEntry = m_elements.back(); xCurrentElement = pEntry->m_xElement; #if OSL_DEBUG_LEVEL > 0 sal_Int32 nUid; OUString aLocalName; getElementName( rQElementName, &nUid, &aLocalName ); OSL_ASSERT( xCurrentElement->getLocalName() == aLocalName ); OSL_ASSERT( xCurrentElement->getUid() == nUid ); #endif // pop prefixes for ( sal_Int32 nPos = pEntry->m_prefixes.size(); nPos--; ) { popPrefix( pEntry->m_prefixes[ nPos ] ); } m_elements.pop_back(); delete pEntry; } xCurrentElement->endElement(); } //______________________________________________________________________________ void DocumentHandlerImpl::characters( OUString const & rChars ) throw (xml::sax::SAXException, RuntimeException) { Reference< xml::input::XElement > xCurrentElement( getCurrentElement() ); if (xCurrentElement.is()) xCurrentElement->characters( rChars ); } //______________________________________________________________________________ void DocumentHandlerImpl::ignorableWhitespace( OUString const & rWhitespaces ) throw (xml::sax::SAXException, RuntimeException) { Reference< xml::input::XElement > xCurrentElement( getCurrentElement() ); if (xCurrentElement.is()) xCurrentElement->ignorableWhitespace( rWhitespaces ); } //______________________________________________________________________________ void DocumentHandlerImpl::processingInstruction( OUString const & rTarget, OUString const & rData ) throw (xml::sax::SAXException, RuntimeException) { Reference< xml::input::XElement > xCurrentElement( getCurrentElement() ); if (xCurrentElement.is()) xCurrentElement->processingInstruction( rTarget, rData ); else m_xRoot->processingInstruction( rTarget, rData ); } //______________________________________________________________________________ void DocumentHandlerImpl::setDocumentLocator( Reference< xml::sax::XLocator > const & xLocator ) throw (xml::sax::SAXException, RuntimeException) { m_xRoot->setDocumentLocator( xLocator ); } //############################################################################## // XAttributes //______________________________________________________________________________ sal_Int32 ExtendedAttributes::getIndexByQName( OUString const & rQName ) throw (RuntimeException) { for ( sal_Int32 nPos = m_nAttributes; nPos--; ) { if (m_pQNames[ nPos ].equals( rQName )) { return nPos; } } return -1; } //______________________________________________________________________________ sal_Int32 ExtendedAttributes::getLength() throw (RuntimeException) { return m_nAttributes; } //______________________________________________________________________________ OUString ExtendedAttributes::getLocalNameByIndex( sal_Int32 nIndex ) throw (RuntimeException) { if (nIndex < m_nAttributes) return m_pLocalNames[ nIndex ]; else return OUString(); } //______________________________________________________________________________ OUString ExtendedAttributes::getQNameByIndex( sal_Int32 nIndex ) throw (RuntimeException) { if (nIndex < m_nAttributes) return m_pQNames[ nIndex ]; else return OUString(); } //______________________________________________________________________________ OUString ExtendedAttributes::getTypeByIndex( sal_Int32 nIndex ) throw (RuntimeException) { static_cast(nIndex); OSL_ASSERT( nIndex < m_nAttributes ); return OUString(); // unsupported } //______________________________________________________________________________ OUString ExtendedAttributes::getValueByIndex( sal_Int32 nIndex ) throw (RuntimeException) { if (nIndex < m_nAttributes) return m_pValues[ nIndex ]; else return OUString(); } //______________________________________________________________________________ sal_Int32 ExtendedAttributes::getIndexByUidName( sal_Int32 nUid, OUString const & rLocalName ) throw (RuntimeException) { for ( sal_Int32 nPos = m_nAttributes; nPos--; ) { if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName) { return nPos; } } return -1; } //______________________________________________________________________________ sal_Int32 ExtendedAttributes::getUidByIndex( sal_Int32 nIndex ) throw (RuntimeException) { if (nIndex < m_nAttributes) return m_pUids[ nIndex ]; else return -1; } //______________________________________________________________________________ OUString ExtendedAttributes::getValueByUidName( sal_Int32 nUid, OUString const & rLocalName ) throw (RuntimeException) { for ( sal_Int32 nPos = m_nAttributes; nPos--; ) { if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName) { return m_pValues[ nPos ]; } } return OUString(); } //############################################################################## //============================================================================== Reference< xml::sax::XDocumentHandler > SAL_CALL createDocumentHandler( Reference< xml::input::XRoot > const & xRoot, bool bSingleThreadedUse ) SAL_THROW( () ) { OSL_ASSERT( xRoot.is() ); if (xRoot.is()) { return static_cast< xml::sax::XDocumentHandler * >( new DocumentHandlerImpl( xRoot, bSingleThreadedUse ) ); } return Reference< xml::sax::XDocumentHandler >(); } //------------------------------------------------------------------------------ Reference< XInterface > SAL_CALL create_DocumentHandlerImpl( Reference< XComponentContext > const & ) SAL_THROW( (Exception) ) { return static_cast< ::cppu::OWeakObject * >( new DocumentHandlerImpl( Reference< xml::input::XRoot >(), false /* mt use */ ) ); } }