1f9b72d11SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3f9b72d11SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4f9b72d11SAndrew Rist * or more contributor license agreements. See the NOTICE file 5f9b72d11SAndrew Rist * distributed with this work for additional information 6f9b72d11SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7f9b72d11SAndrew Rist * to you under the Apache License, Version 2.0 (the 8f9b72d11SAndrew Rist * "License"); you may not use this file except in compliance 9f9b72d11SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11f9b72d11SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13f9b72d11SAndrew Rist * Unless required by applicable law or agreed to in writing, 14f9b72d11SAndrew Rist * software distributed under the License is distributed on an 15f9b72d11SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16f9b72d11SAndrew Rist * KIND, either express or implied. See the License for the 17f9b72d11SAndrew Rist * specific language governing permissions and limitations 18f9b72d11SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20f9b72d11SAndrew Rist *************************************************************/ 21f9b72d11SAndrew Rist 22f9b72d11SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir //#include <stdlib.h> 25cdf0e10cSrcweir //#include <sal/alloca.h> 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <boost/scoped_ptr.hpp> 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <osl/diagnose.h> 30cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp> 33cdf0e10cSrcweir #include <com/sun/star/xml/sax/XFastContextHandler.hpp> 34cdf0e10cSrcweir #include <com/sun/star/xml/sax/SAXParseException.hpp> 35cdf0e10cSrcweir #include <com/sun/star/xml/sax/FastToken.hpp> 36cdf0e10cSrcweir 37cdf0e10cSrcweir #include "fastparser.hxx" 38cdf0e10cSrcweir 39cdf0e10cSrcweir #include <string.h> 40cdf0e10cSrcweir 41cdf0e10cSrcweir using ::rtl::OString; 42cdf0e10cSrcweir using ::rtl::OUString; 43cdf0e10cSrcweir using ::rtl::OUStringBuffer; 44cdf0e10cSrcweir using namespace ::std; 45cdf0e10cSrcweir using namespace ::osl; 46cdf0e10cSrcweir using namespace ::cppu; 47cdf0e10cSrcweir using namespace ::com::sun::star::uno; 48cdf0e10cSrcweir using namespace ::com::sun::star::lang; 49cdf0e10cSrcweir using namespace ::com::sun::star::xml::sax; 50cdf0e10cSrcweir //using namespace ::com::sun::star::util; 51cdf0e10cSrcweir using namespace ::com::sun::star::io; 52cdf0e10cSrcweir 53cdf0e10cSrcweir namespace sax_fastparser { 54cdf0e10cSrcweir 55cdf0e10cSrcweir // -------------------------------------------------------------------- 56cdf0e10cSrcweir 57cdf0e10cSrcweir struct SaxContextImpl 58cdf0e10cSrcweir { 59cdf0e10cSrcweir Reference< XFastContextHandler > mxContext; 60cdf0e10cSrcweir sal_uInt32 mnNamespaceCount; 61cdf0e10cSrcweir sal_Int32 mnElementToken; 62cdf0e10cSrcweir OUString maNamespace; 63cdf0e10cSrcweir OUString maElementName; 64cdf0e10cSrcweir 65cdf0e10cSrcweir SaxContextImpl() { mnNamespaceCount = 0; mnElementToken = 0; } 66cdf0e10cSrcweir SaxContextImpl( const SaxContextImplPtr& p ) { mnNamespaceCount = p->mnNamespaceCount; mnElementToken = p->mnElementToken; maNamespace = p->maNamespace; } 67cdf0e10cSrcweir }; 68cdf0e10cSrcweir 69cdf0e10cSrcweir // -------------------------------------------------------------------- 70cdf0e10cSrcweir 71cdf0e10cSrcweir struct NamespaceDefine 72cdf0e10cSrcweir { 73cdf0e10cSrcweir OString maPrefix; 74cdf0e10cSrcweir sal_Int32 mnToken; 75cdf0e10cSrcweir OUString maNamespaceURL; 76cdf0e10cSrcweir 77cdf0e10cSrcweir NamespaceDefine( const OString& rPrefix, sal_Int32 nToken, const OUString& rNamespaceURL ) : maPrefix( rPrefix ), mnToken( nToken ), maNamespaceURL( rNamespaceURL ) {} 78cdf0e10cSrcweir }; 79cdf0e10cSrcweir 80cdf0e10cSrcweir // -------------------------------------------------------------------- 81cdf0e10cSrcweir // FastLocatorImpl 82cdf0e10cSrcweir // -------------------------------------------------------------------- 83cdf0e10cSrcweir 84cdf0e10cSrcweir class FastSaxParser; 85cdf0e10cSrcweir 86cdf0e10cSrcweir class FastLocatorImpl : public WeakImplHelper1< XLocator > 87cdf0e10cSrcweir { 88cdf0e10cSrcweir public: 89cdf0e10cSrcweir FastLocatorImpl( FastSaxParser *p ) : mpParser(p) {} 90cdf0e10cSrcweir 91cdf0e10cSrcweir void dispose() { mpParser = 0; } 92cdf0e10cSrcweir void checkDispose() throw (RuntimeException) { if( !mpParser ) throw DisposedException(); } 93cdf0e10cSrcweir 94cdf0e10cSrcweir //XLocator 95cdf0e10cSrcweir virtual sal_Int32 SAL_CALL getColumnNumber(void) throw (RuntimeException); 96cdf0e10cSrcweir virtual sal_Int32 SAL_CALL getLineNumber(void) throw (RuntimeException); 97cdf0e10cSrcweir virtual OUString SAL_CALL getPublicId(void) throw (RuntimeException); 98cdf0e10cSrcweir virtual OUString SAL_CALL getSystemId(void) throw (RuntimeException); 99cdf0e10cSrcweir 100cdf0e10cSrcweir private: 101cdf0e10cSrcweir FastSaxParser *mpParser; 102cdf0e10cSrcweir }; 103cdf0e10cSrcweir 104cdf0e10cSrcweir // -------------------------------------------------------------------- 105cdf0e10cSrcweir // FastSaxParser 106cdf0e10cSrcweir // -------------------------------------------------------------------- 107cdf0e10cSrcweir 108cdf0e10cSrcweir //--------------------------------------------- 109cdf0e10cSrcweir // the implementation part 110cdf0e10cSrcweir //--------------------------------------------- 111cdf0e10cSrcweir 112cdf0e10cSrcweir extern "C" { 113cdf0e10cSrcweir 114cdf0e10cSrcweir static void call_callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts) 115cdf0e10cSrcweir { 116cdf0e10cSrcweir FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( userData ); 117cdf0e10cSrcweir pFastParser->callbackStartElement( name, atts ); 118cdf0e10cSrcweir } 119cdf0e10cSrcweir 120cdf0e10cSrcweir static void call_callbackEndElement(void *userData, const XML_Char *name) 121cdf0e10cSrcweir { 122cdf0e10cSrcweir FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( userData ); 123cdf0e10cSrcweir pFastParser->callbackEndElement( name ); 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir static void call_callbackCharacters( void *userData , const XML_Char *s , int nLen ) 127cdf0e10cSrcweir { 128cdf0e10cSrcweir FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( userData ); 129cdf0e10cSrcweir pFastParser->callbackCharacters( s, nLen ); 130cdf0e10cSrcweir } 131cdf0e10cSrcweir 132cdf0e10cSrcweir static int call_callbackExternalEntityRef( XML_Parser parser, 133cdf0e10cSrcweir const XML_Char *openEntityNames, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId ) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( XML_GetUserData( parser ) ); 136cdf0e10cSrcweir return pFastParser->callbackExternalEntityRef( parser, openEntityNames, base, systemId, publicId ); 137cdf0e10cSrcweir } 138cdf0e10cSrcweir 139cdf0e10cSrcweir } // extern "C" 140cdf0e10cSrcweir 141cdf0e10cSrcweir // -------------------------------------------------------------------- 142cdf0e10cSrcweir // FastLocatorImpl implementation 143cdf0e10cSrcweir // -------------------------------------------------------------------- 144cdf0e10cSrcweir 145cdf0e10cSrcweir sal_Int32 SAL_CALL FastLocatorImpl::getColumnNumber(void) throw (RuntimeException) 146cdf0e10cSrcweir { 147cdf0e10cSrcweir checkDispose(); 148cdf0e10cSrcweir return XML_GetCurrentColumnNumber( mpParser->getEntity().mpParser ); 149cdf0e10cSrcweir } 150cdf0e10cSrcweir 151cdf0e10cSrcweir // -------------------------------------------------------------------- 152cdf0e10cSrcweir 153cdf0e10cSrcweir sal_Int32 SAL_CALL FastLocatorImpl::getLineNumber(void) throw (RuntimeException) 154cdf0e10cSrcweir { 155cdf0e10cSrcweir checkDispose(); 156cdf0e10cSrcweir return XML_GetCurrentLineNumber( mpParser->getEntity().mpParser ); 157cdf0e10cSrcweir } 158cdf0e10cSrcweir 159cdf0e10cSrcweir // -------------------------------------------------------------------- 160cdf0e10cSrcweir 161cdf0e10cSrcweir OUString SAL_CALL FastLocatorImpl::getPublicId(void) throw (RuntimeException) 162cdf0e10cSrcweir { 163cdf0e10cSrcweir checkDispose(); 164cdf0e10cSrcweir return mpParser->getEntity().maStructSource.sPublicId; 165cdf0e10cSrcweir } 166cdf0e10cSrcweir // -------------------------------------------------------------------- 167cdf0e10cSrcweir 168cdf0e10cSrcweir OUString SAL_CALL FastLocatorImpl::getSystemId(void) throw (RuntimeException) 169cdf0e10cSrcweir { 170cdf0e10cSrcweir checkDispose(); 171cdf0e10cSrcweir return mpParser->getEntity().maStructSource.sSystemId; 172cdf0e10cSrcweir } 173cdf0e10cSrcweir 174cdf0e10cSrcweir // -------------------------------------------------------------------- 175cdf0e10cSrcweir 176cdf0e10cSrcweir ParserData::ParserData() 177cdf0e10cSrcweir { 178cdf0e10cSrcweir } 179cdf0e10cSrcweir 180cdf0e10cSrcweir ParserData::~ParserData() 181cdf0e10cSrcweir { 182cdf0e10cSrcweir } 183cdf0e10cSrcweir 184cdf0e10cSrcweir // -------------------------------------------------------------------- 185cdf0e10cSrcweir 186cdf0e10cSrcweir Entity::Entity( const ParserData& rData ) : 187cdf0e10cSrcweir ParserData( rData ) 188cdf0e10cSrcweir { 189cdf0e10cSrcweir // performance-Improvment. Reference is needed when calling the startTag callback. 190cdf0e10cSrcweir // Handing out the same object with every call is allowed (see sax-specification) 191cdf0e10cSrcweir mxAttributes.set( new FastAttributeList( mxTokenHandler ) ); 192cdf0e10cSrcweir } 193cdf0e10cSrcweir 194cdf0e10cSrcweir Entity::~Entity() 195cdf0e10cSrcweir { 196cdf0e10cSrcweir } 197cdf0e10cSrcweir 198cdf0e10cSrcweir // -------------------------------------------------------------------- 199cdf0e10cSrcweir // FastSaxParser implementation 200cdf0e10cSrcweir // -------------------------------------------------------------------- 201cdf0e10cSrcweir 202cdf0e10cSrcweir FastSaxParser::FastSaxParser() 203cdf0e10cSrcweir { 204cdf0e10cSrcweir mxDocumentLocator.set( new FastLocatorImpl( this ) ); 205cdf0e10cSrcweir } 206cdf0e10cSrcweir 207cdf0e10cSrcweir // -------------------------------------------------------------------- 208cdf0e10cSrcweir 209cdf0e10cSrcweir FastSaxParser::~FastSaxParser() 210cdf0e10cSrcweir { 211cdf0e10cSrcweir if( mxDocumentLocator.is() ) 212cdf0e10cSrcweir mxDocumentLocator->dispose(); 213cdf0e10cSrcweir } 214cdf0e10cSrcweir 215cdf0e10cSrcweir // -------------------------------------------------------------------- 216cdf0e10cSrcweir 217cdf0e10cSrcweir void FastSaxParser::pushContext() 218cdf0e10cSrcweir { 219cdf0e10cSrcweir Entity& rEntity = getEntity(); 220cdf0e10cSrcweir if( rEntity.maContextStack.empty() ) 221cdf0e10cSrcweir { 222cdf0e10cSrcweir rEntity.maContextStack.push( SaxContextImplPtr( new SaxContextImpl ) ); 223cdf0e10cSrcweir DefineNamespace( OString("xml"), "http://www.w3.org/XML/1998/namespace"); 224cdf0e10cSrcweir } 225cdf0e10cSrcweir else 226cdf0e10cSrcweir { 227cdf0e10cSrcweir rEntity.maContextStack.push( SaxContextImplPtr( new SaxContextImpl( rEntity.maContextStack.top() ) ) ); 228cdf0e10cSrcweir } 229cdf0e10cSrcweir } 230cdf0e10cSrcweir 231cdf0e10cSrcweir // -------------------------------------------------------------------- 232cdf0e10cSrcweir 233cdf0e10cSrcweir void FastSaxParser::popContext() 234cdf0e10cSrcweir { 235cdf0e10cSrcweir Entity& rEntity = getEntity(); 236cdf0e10cSrcweir OSL_ENSURE( !rEntity.maContextStack.empty(), "sax::FastSaxParser::popContext(), pop without push?" ); 237cdf0e10cSrcweir if( !rEntity.maContextStack.empty() ) 238cdf0e10cSrcweir rEntity.maContextStack.pop(); 239cdf0e10cSrcweir } 240cdf0e10cSrcweir 241cdf0e10cSrcweir // -------------------------------------------------------------------- 242cdf0e10cSrcweir 243cdf0e10cSrcweir void FastSaxParser::DefineNamespace( const OString& rPrefix, const sal_Char* pNamespaceURL ) 244cdf0e10cSrcweir { 245cdf0e10cSrcweir Entity& rEntity = getEntity(); 246cdf0e10cSrcweir OSL_ENSURE( !rEntity.maContextStack.empty(), "sax::FastSaxParser::DefineNamespace(), I need a context!" ); 247cdf0e10cSrcweir if( !rEntity.maContextStack.empty() ) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir sal_uInt32 nOffset = rEntity.maContextStack.top()->mnNamespaceCount++; 250cdf0e10cSrcweir 251cdf0e10cSrcweir if( rEntity.maNamespaceDefines.size() <= nOffset ) 252cdf0e10cSrcweir rEntity.maNamespaceDefines.resize( rEntity.maNamespaceDefines.size() + 64 ); 253cdf0e10cSrcweir 254cdf0e10cSrcweir const OUString aNamespaceURL( pNamespaceURL, strlen( pNamespaceURL ), RTL_TEXTENCODING_UTF8 ); 255cdf0e10cSrcweir rEntity.maNamespaceDefines[nOffset].reset( new NamespaceDefine( rPrefix, GetNamespaceToken( aNamespaceURL ), aNamespaceURL ) ); 256cdf0e10cSrcweir } 257cdf0e10cSrcweir } 258cdf0e10cSrcweir 259cdf0e10cSrcweir // -------------------------------------------------------------------- 260cdf0e10cSrcweir 261cdf0e10cSrcweir sal_Int32 FastSaxParser::GetToken( const OString& rToken ) 262cdf0e10cSrcweir { 263cdf0e10cSrcweir Sequence< sal_Int8 > aSeq( (sal_Int8*)rToken.getStr(), rToken.getLength() ); 264cdf0e10cSrcweir 265cdf0e10cSrcweir return getEntity().mxTokenHandler->getTokenFromUTF8( aSeq ); 266cdf0e10cSrcweir } 267cdf0e10cSrcweir 268cdf0e10cSrcweir sal_Int32 FastSaxParser::GetToken( const sal_Char* pToken, sal_Int32 nLen /* = 0 */ ) 269cdf0e10cSrcweir { 270cdf0e10cSrcweir if( !nLen ) 271cdf0e10cSrcweir nLen = strlen( pToken ); 272cdf0e10cSrcweir 273cdf0e10cSrcweir Sequence< sal_Int8 > aSeq( (sal_Int8*)pToken, nLen ); 274cdf0e10cSrcweir 275cdf0e10cSrcweir return getEntity().mxTokenHandler->getTokenFromUTF8( aSeq ); 276cdf0e10cSrcweir } 277cdf0e10cSrcweir 278cdf0e10cSrcweir // -------------------------------------------------------------------- 279cdf0e10cSrcweir 280cdf0e10cSrcweir sal_Int32 FastSaxParser::GetTokenWithPrefix( const OString& rPrefix, const OString& rName ) throw (SAXException) 281cdf0e10cSrcweir { 282cdf0e10cSrcweir sal_Int32 nNamespaceToken = FastToken::DONTKNOW; 283cdf0e10cSrcweir 284cdf0e10cSrcweir Entity& rEntity = getEntity(); 285cdf0e10cSrcweir sal_uInt32 nNamespace = rEntity.maContextStack.top()->mnNamespaceCount; 286cdf0e10cSrcweir while( nNamespace-- ) 287cdf0e10cSrcweir { 288cdf0e10cSrcweir if( rEntity.maNamespaceDefines[nNamespace]->maPrefix == rPrefix ) 289cdf0e10cSrcweir { 290cdf0e10cSrcweir nNamespaceToken = rEntity.maNamespaceDefines[nNamespace]->mnToken; 291cdf0e10cSrcweir break; 292cdf0e10cSrcweir } 293cdf0e10cSrcweir 294cdf0e10cSrcweir if( !nNamespace ) 295cdf0e10cSrcweir throw SAXException(); // prefix that has no defined namespace url 296cdf0e10cSrcweir } 297cdf0e10cSrcweir 298cdf0e10cSrcweir if( nNamespaceToken != FastToken::DONTKNOW ) 299cdf0e10cSrcweir { 300cdf0e10cSrcweir sal_Int32 nNameToken = GetToken( rName.getStr(), rName.getLength() ); 301cdf0e10cSrcweir if( nNameToken != FastToken::DONTKNOW ) 302cdf0e10cSrcweir return nNamespaceToken | nNameToken; 303cdf0e10cSrcweir } 304cdf0e10cSrcweir 305cdf0e10cSrcweir return FastToken::DONTKNOW; 306cdf0e10cSrcweir } 307cdf0e10cSrcweir 308cdf0e10cSrcweir sal_Int32 FastSaxParser::GetTokenWithPrefix( const sal_Char*pPrefix, int nPrefixLen, const sal_Char* pName, int nNameLen ) throw (SAXException) 309cdf0e10cSrcweir { 310cdf0e10cSrcweir sal_Int32 nNamespaceToken = FastToken::DONTKNOW; 311cdf0e10cSrcweir 312cdf0e10cSrcweir Entity& rEntity = getEntity(); 313cdf0e10cSrcweir sal_uInt32 nNamespace = rEntity.maContextStack.top()->mnNamespaceCount; 314cdf0e10cSrcweir while( nNamespace-- ) 315cdf0e10cSrcweir { 316cdf0e10cSrcweir const OString& rPrefix( rEntity.maNamespaceDefines[nNamespace]->maPrefix ); 317cdf0e10cSrcweir if( (rPrefix.getLength() == nPrefixLen) && 318cdf0e10cSrcweir (strncmp( rPrefix.getStr(), pPrefix, nPrefixLen ) == 0 ) ) 319cdf0e10cSrcweir { 320cdf0e10cSrcweir nNamespaceToken = rEntity.maNamespaceDefines[nNamespace]->mnToken; 321cdf0e10cSrcweir break; 322cdf0e10cSrcweir } 323cdf0e10cSrcweir 324cdf0e10cSrcweir if( !nNamespace ) 325cdf0e10cSrcweir throw SAXException(); // prefix that has no defined namespace url 326cdf0e10cSrcweir } 327cdf0e10cSrcweir 328cdf0e10cSrcweir if( nNamespaceToken != FastToken::DONTKNOW ) 329cdf0e10cSrcweir { 330cdf0e10cSrcweir sal_Int32 nNameToken = GetToken( pName, nNameLen ); 331cdf0e10cSrcweir if( nNameToken != FastToken::DONTKNOW ) 332cdf0e10cSrcweir return nNamespaceToken | nNameToken; 333cdf0e10cSrcweir } 334cdf0e10cSrcweir 335cdf0e10cSrcweir return FastToken::DONTKNOW; 336cdf0e10cSrcweir } 337cdf0e10cSrcweir 338cdf0e10cSrcweir // -------------------------------------------------------------------- 339cdf0e10cSrcweir 340cdf0e10cSrcweir sal_Int32 FastSaxParser::GetNamespaceToken( const OUString& rNamespaceURL ) 341cdf0e10cSrcweir { 342cdf0e10cSrcweir NamespaceMap::iterator aIter( maNamespaceMap.find( rNamespaceURL ) ); 343cdf0e10cSrcweir if( aIter != maNamespaceMap.end() ) 344cdf0e10cSrcweir return (*aIter).second; 345cdf0e10cSrcweir else 346cdf0e10cSrcweir return FastToken::DONTKNOW; 347cdf0e10cSrcweir } 348cdf0e10cSrcweir 349cdf0e10cSrcweir // -------------------------------------------------------------------- 350cdf0e10cSrcweir 351cdf0e10cSrcweir OUString FastSaxParser::GetNamespaceURL( const OString& rPrefix ) throw (SAXException) 352cdf0e10cSrcweir { 353cdf0e10cSrcweir Entity& rEntity = getEntity(); 354cdf0e10cSrcweir if( !rEntity.maContextStack.empty() ) 355cdf0e10cSrcweir { 356cdf0e10cSrcweir sal_uInt32 nNamespace = rEntity.maContextStack.top()->mnNamespaceCount; 357cdf0e10cSrcweir while( nNamespace-- ) 358cdf0e10cSrcweir if( rEntity.maNamespaceDefines[nNamespace]->maPrefix == rPrefix ) 359cdf0e10cSrcweir return rEntity.maNamespaceDefines[nNamespace]->maNamespaceURL; 360cdf0e10cSrcweir } 361cdf0e10cSrcweir 362cdf0e10cSrcweir throw SAXException(); // prefix that has no defined namespace url 363cdf0e10cSrcweir } 364cdf0e10cSrcweir 365cdf0e10cSrcweir OUString FastSaxParser::GetNamespaceURL( const sal_Char*pPrefix, int nPrefixLen ) throw(SAXException) 366cdf0e10cSrcweir { 367cdf0e10cSrcweir Entity& rEntity = getEntity(); 368cdf0e10cSrcweir if( pPrefix && !rEntity.maContextStack.empty() ) 369cdf0e10cSrcweir { 370cdf0e10cSrcweir sal_uInt32 nNamespace = rEntity.maContextStack.top()->mnNamespaceCount; 371cdf0e10cSrcweir while( nNamespace-- ) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir const OString& rPrefix( rEntity.maNamespaceDefines[nNamespace]->maPrefix ); 374cdf0e10cSrcweir if( (rPrefix.getLength() == nPrefixLen) && 375cdf0e10cSrcweir (strncmp( rPrefix.getStr(), pPrefix, nPrefixLen ) == 0 ) ) 376cdf0e10cSrcweir { 377cdf0e10cSrcweir return rEntity.maNamespaceDefines[nNamespace]->maNamespaceURL; 378cdf0e10cSrcweir } 379cdf0e10cSrcweir } 380cdf0e10cSrcweir } 381cdf0e10cSrcweir 382cdf0e10cSrcweir throw SAXException(); // prefix that has no defined namespace url 383cdf0e10cSrcweir } 384cdf0e10cSrcweir 385cdf0e10cSrcweir // -------------------------------------------------------------------- 386cdf0e10cSrcweir 387cdf0e10cSrcweir sal_Int32 FastSaxParser::GetTokenWithNamespaceURL( const OUString& rNamespaceURL, const sal_Char* pName, int nNameLen ) 388cdf0e10cSrcweir { 389cdf0e10cSrcweir sal_Int32 nNamespaceToken = GetNamespaceToken( rNamespaceURL ); 390cdf0e10cSrcweir 391cdf0e10cSrcweir if( nNamespaceToken != FastToken::DONTKNOW ) 392cdf0e10cSrcweir { 393cdf0e10cSrcweir sal_Int32 nNameToken = GetToken( pName, nNameLen ); 394cdf0e10cSrcweir if( nNameToken != FastToken::DONTKNOW ) 395cdf0e10cSrcweir return nNamespaceToken | nNameToken; 396cdf0e10cSrcweir } 397cdf0e10cSrcweir 398cdf0e10cSrcweir return FastToken::DONTKNOW; 399cdf0e10cSrcweir } 400cdf0e10cSrcweir 401cdf0e10cSrcweir // -------------------------------------------------------------------- 402cdf0e10cSrcweir 403cdf0e10cSrcweir void FastSaxParser::splitName( const XML_Char *pwName, const XML_Char *&rpPrefix, sal_Int32 &rPrefixLen, const XML_Char *&rpName, sal_Int32 &rNameLen ) 404cdf0e10cSrcweir { 405cdf0e10cSrcweir XML_Char *p; 406cdf0e10cSrcweir for( p = const_cast< XML_Char* >( pwName ), rNameLen = 0, rPrefixLen = 0; *p; p++ ) 407cdf0e10cSrcweir { 408cdf0e10cSrcweir if( *p == ':' ) 409cdf0e10cSrcweir { 410cdf0e10cSrcweir rPrefixLen = p - pwName; 411cdf0e10cSrcweir rNameLen = 0; 412cdf0e10cSrcweir } 413cdf0e10cSrcweir else 414cdf0e10cSrcweir { 415cdf0e10cSrcweir rNameLen++; 416cdf0e10cSrcweir } 417cdf0e10cSrcweir } 418cdf0e10cSrcweir if( rPrefixLen ) 419cdf0e10cSrcweir { 420cdf0e10cSrcweir rpPrefix = pwName; 421cdf0e10cSrcweir rpName = &pwName[ rPrefixLen + 1 ]; 422cdf0e10cSrcweir } 423cdf0e10cSrcweir else 424cdf0e10cSrcweir { 425cdf0e10cSrcweir rpPrefix = 0; 426cdf0e10cSrcweir rpName = pwName; 427cdf0e10cSrcweir } 428cdf0e10cSrcweir } 429cdf0e10cSrcweir 430cdf0e10cSrcweir /*************** 431cdf0e10cSrcweir * 432cdf0e10cSrcweir * parseStream does Parser-startup initializations. The FastSaxParser::parse() method does 433cdf0e10cSrcweir * the file-specific initialization work. (During a parser run, external files may be opened) 434cdf0e10cSrcweir * 435cdf0e10cSrcweir ****************/ 436cdf0e10cSrcweir void FastSaxParser::parseStream( const InputSource& maStructSource) throw (SAXException, IOException, RuntimeException) 437cdf0e10cSrcweir { 438cdf0e10cSrcweir // Only one text at one time 439cdf0e10cSrcweir MutexGuard guard( maMutex ); 440cdf0e10cSrcweir 441cdf0e10cSrcweir Entity entity( maData ); 442cdf0e10cSrcweir entity.maStructSource = maStructSource; 443cdf0e10cSrcweir 444cdf0e10cSrcweir if( !entity.maStructSource.aInputStream.is() ) 445cdf0e10cSrcweir throw SAXException( OUString( RTL_CONSTASCII_USTRINGPARAM( "No input source" ) ), Reference< XInterface >(), Any() ); 446cdf0e10cSrcweir 447cdf0e10cSrcweir entity.maConverter.setInputStream( entity.maStructSource.aInputStream ); 448cdf0e10cSrcweir if( entity.maStructSource.sEncoding.getLength() ) 449cdf0e10cSrcweir entity.maConverter.setEncoding( OUStringToOString( entity.maStructSource.sEncoding, RTL_TEXTENCODING_ASCII_US ) ); 450cdf0e10cSrcweir 451cdf0e10cSrcweir // create parser with proper encoding 452cdf0e10cSrcweir entity.mpParser = XML_ParserCreate( 0 ); 453cdf0e10cSrcweir if( !entity.mpParser ) 454cdf0e10cSrcweir throw SAXException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Couldn't create parser" ) ), Reference< XInterface >(), Any() ); 455cdf0e10cSrcweir 456cdf0e10cSrcweir // set all necessary C-Callbacks 457cdf0e10cSrcweir XML_SetUserData( entity.mpParser, this ); 458cdf0e10cSrcweir XML_SetElementHandler( entity.mpParser, call_callbackStartElement, call_callbackEndElement ); 459cdf0e10cSrcweir XML_SetCharacterDataHandler( entity.mpParser, call_callbackCharacters ); 460cdf0e10cSrcweir XML_SetExternalEntityRefHandler( entity.mpParser, call_callbackExternalEntityRef ); 461cdf0e10cSrcweir 462cdf0e10cSrcweir pushEntity( entity ); 463cdf0e10cSrcweir try 464cdf0e10cSrcweir { 465cdf0e10cSrcweir // start the document 466cdf0e10cSrcweir if( entity.mxDocumentHandler.is() ) 467cdf0e10cSrcweir { 468cdf0e10cSrcweir Reference< XLocator > xLoc( mxDocumentLocator.get() ); 469cdf0e10cSrcweir entity.mxDocumentHandler->setDocumentLocator( xLoc ); 470cdf0e10cSrcweir entity.mxDocumentHandler->startDocument(); 471cdf0e10cSrcweir } 472cdf0e10cSrcweir 473cdf0e10cSrcweir parse(); 474cdf0e10cSrcweir 475cdf0e10cSrcweir // finish document 476cdf0e10cSrcweir if( entity.mxDocumentHandler.is() ) 477cdf0e10cSrcweir { 478cdf0e10cSrcweir entity.mxDocumentHandler->endDocument(); 479cdf0e10cSrcweir } 480cdf0e10cSrcweir } 481cdf0e10cSrcweir catch( SAXException & ) 482cdf0e10cSrcweir { 483cdf0e10cSrcweir popEntity(); 484cdf0e10cSrcweir XML_ParserFree( entity.mpParser ); 485cdf0e10cSrcweir throw; 486cdf0e10cSrcweir } 487cdf0e10cSrcweir catch( IOException & ) 488cdf0e10cSrcweir { 489cdf0e10cSrcweir popEntity(); 490cdf0e10cSrcweir XML_ParserFree( entity.mpParser ); 491cdf0e10cSrcweir throw; 492cdf0e10cSrcweir } 493cdf0e10cSrcweir catch( RuntimeException & ) 494cdf0e10cSrcweir { 495cdf0e10cSrcweir popEntity(); 496cdf0e10cSrcweir XML_ParserFree( entity.mpParser ); 497cdf0e10cSrcweir throw; 498cdf0e10cSrcweir } 499cdf0e10cSrcweir 500cdf0e10cSrcweir popEntity(); 501cdf0e10cSrcweir XML_ParserFree( entity.mpParser ); 502cdf0e10cSrcweir } 503cdf0e10cSrcweir 504cdf0e10cSrcweir void FastSaxParser::setFastDocumentHandler( const Reference< XFastDocumentHandler >& Handler ) throw (RuntimeException) 505cdf0e10cSrcweir { 506cdf0e10cSrcweir maData.mxDocumentHandler = Handler; 507cdf0e10cSrcweir } 508cdf0e10cSrcweir 509cdf0e10cSrcweir void SAL_CALL FastSaxParser::setTokenHandler( const Reference< XFastTokenHandler >& Handler ) throw (RuntimeException) 510cdf0e10cSrcweir { 511cdf0e10cSrcweir maData.mxTokenHandler = Handler; 512cdf0e10cSrcweir } 513cdf0e10cSrcweir 514cdf0e10cSrcweir void SAL_CALL FastSaxParser::registerNamespace( const OUString& NamespaceURL, sal_Int32 NamespaceToken ) throw (IllegalArgumentException, RuntimeException) 515cdf0e10cSrcweir { 516cdf0e10cSrcweir if( NamespaceToken >= FastToken::NAMESPACE ) 517cdf0e10cSrcweir { 518cdf0e10cSrcweir if( GetNamespaceToken( NamespaceURL ) == FastToken::DONTKNOW ) 519cdf0e10cSrcweir { 520cdf0e10cSrcweir maNamespaceMap[ NamespaceURL ] = NamespaceToken; 521cdf0e10cSrcweir return; 522cdf0e10cSrcweir } 523cdf0e10cSrcweir } 524cdf0e10cSrcweir throw IllegalArgumentException(); 525cdf0e10cSrcweir } 526cdf0e10cSrcweir 527cdf0e10cSrcweir void FastSaxParser::setErrorHandler(const Reference< XErrorHandler > & Handler) throw (RuntimeException) 528cdf0e10cSrcweir { 529cdf0e10cSrcweir maData.mxErrorHandler = Handler; 530cdf0e10cSrcweir } 531cdf0e10cSrcweir 532cdf0e10cSrcweir void FastSaxParser::setEntityResolver(const Reference < XEntityResolver > & Resolver) throw (RuntimeException) 533cdf0e10cSrcweir { 534cdf0e10cSrcweir maData.mxEntityResolver = Resolver; 535cdf0e10cSrcweir } 536cdf0e10cSrcweir 537cdf0e10cSrcweir void FastSaxParser::setLocale( const Locale & Locale ) throw (RuntimeException) 538cdf0e10cSrcweir { 539cdf0e10cSrcweir maData.maLocale = Locale; 540cdf0e10cSrcweir } 541cdf0e10cSrcweir 542*85ec52e3SDamjan Jovanovic OUString FastSaxParser::getImplementationName_Static(void) 543*85ec52e3SDamjan Jovanovic { 544*85ec52e3SDamjan Jovanovic return OUString::createFromAscii( PARSER_IMPLEMENTATION_NAME ); 545*85ec52e3SDamjan Jovanovic } 546*85ec52e3SDamjan Jovanovic 547cdf0e10cSrcweir Sequence< OUString > FastSaxParser::getSupportedServiceNames_Static(void) 548cdf0e10cSrcweir { 549cdf0e10cSrcweir Sequence<OUString> aRet(1); 550cdf0e10cSrcweir aRet.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(PARSER_SERVICE_NAME) ); 551cdf0e10cSrcweir return aRet; 552cdf0e10cSrcweir } 553cdf0e10cSrcweir 554cdf0e10cSrcweir // XServiceInfo 555cdf0e10cSrcweir OUString FastSaxParser::getImplementationName() throw (RuntimeException) 556cdf0e10cSrcweir { 557*85ec52e3SDamjan Jovanovic return getImplementationName_Static(); 558cdf0e10cSrcweir } 559cdf0e10cSrcweir 560cdf0e10cSrcweir // XServiceInfo 561cdf0e10cSrcweir sal_Bool FastSaxParser::supportsService(const OUString& ServiceName) throw (RuntimeException) 562cdf0e10cSrcweir { 563cdf0e10cSrcweir Sequence< OUString > aSNL = getSupportedServiceNames(); 564cdf0e10cSrcweir const OUString * pArray = aSNL.getConstArray(); 565cdf0e10cSrcweir 566cdf0e10cSrcweir for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 567cdf0e10cSrcweir if( pArray[i] == ServiceName ) 568cdf0e10cSrcweir return sal_True; 569cdf0e10cSrcweir 570cdf0e10cSrcweir return sal_False; 571cdf0e10cSrcweir } 572cdf0e10cSrcweir 573cdf0e10cSrcweir // XServiceInfo 574cdf0e10cSrcweir Sequence< OUString > FastSaxParser::getSupportedServiceNames(void) throw (RuntimeException) 575cdf0e10cSrcweir { 576cdf0e10cSrcweir 577cdf0e10cSrcweir Sequence<OUString> seq(1); 578cdf0e10cSrcweir seq.getArray()[0] = OUString::createFromAscii( PARSER_SERVICE_NAME ); 579cdf0e10cSrcweir return seq; 580cdf0e10cSrcweir } 581cdf0e10cSrcweir 582cdf0e10cSrcweir 583cdf0e10cSrcweir /*--------------------------------------- 584cdf0e10cSrcweir * 585cdf0e10cSrcweir * Helper functions and classes 586cdf0e10cSrcweir * 587cdf0e10cSrcweir *-------------------------------------------*/ 588cdf0e10cSrcweir 589cdf0e10cSrcweir namespace { 590cdf0e10cSrcweir 591cdf0e10cSrcweir OUString lclGetErrorMessage( XML_Error xmlE, const OUString& sSystemId, sal_Int32 nLine ) 592cdf0e10cSrcweir { 593cdf0e10cSrcweir const sal_Char* pMessage = ""; 594cdf0e10cSrcweir switch( xmlE ) 595cdf0e10cSrcweir { 596cdf0e10cSrcweir case XML_ERROR_NONE: pMessage = "No"; break; 597cdf0e10cSrcweir case XML_ERROR_NO_MEMORY: pMessage = "no memory"; break; 598cdf0e10cSrcweir case XML_ERROR_SYNTAX: pMessage = "syntax"; break; 599cdf0e10cSrcweir case XML_ERROR_NO_ELEMENTS: pMessage = "no elements"; break; 600cdf0e10cSrcweir case XML_ERROR_INVALID_TOKEN: pMessage = "invalid token"; break; 601cdf0e10cSrcweir case XML_ERROR_UNCLOSED_TOKEN: pMessage = "unclosed token"; break; 602cdf0e10cSrcweir case XML_ERROR_PARTIAL_CHAR: pMessage = "partial char"; break; 603cdf0e10cSrcweir case XML_ERROR_TAG_MISMATCH: pMessage = "tag mismatch"; break; 604cdf0e10cSrcweir case XML_ERROR_DUPLICATE_ATTRIBUTE: pMessage = "duplicate attribute"; break; 605cdf0e10cSrcweir case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: pMessage = "junk after doc element"; break; 606cdf0e10cSrcweir case XML_ERROR_PARAM_ENTITY_REF: pMessage = "parameter entity reference"; break; 607cdf0e10cSrcweir case XML_ERROR_UNDEFINED_ENTITY: pMessage = "undefined entity"; break; 608cdf0e10cSrcweir case XML_ERROR_RECURSIVE_ENTITY_REF: pMessage = "recursive entity reference"; break; 609cdf0e10cSrcweir case XML_ERROR_ASYNC_ENTITY: pMessage = "async entity"; break; 610cdf0e10cSrcweir case XML_ERROR_BAD_CHAR_REF: pMessage = "bad char reference"; break; 611cdf0e10cSrcweir case XML_ERROR_BINARY_ENTITY_REF: pMessage = "binary entity reference"; break; 612cdf0e10cSrcweir case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: pMessage = "attribute external entity reference"; break; 613cdf0e10cSrcweir case XML_ERROR_MISPLACED_XML_PI: pMessage = "misplaced xml processing instruction"; break; 614cdf0e10cSrcweir case XML_ERROR_UNKNOWN_ENCODING: pMessage = "unknown encoding"; break; 615cdf0e10cSrcweir case XML_ERROR_INCORRECT_ENCODING: pMessage = "incorrect encoding"; break; 616cdf0e10cSrcweir case XML_ERROR_UNCLOSED_CDATA_SECTION: pMessage = "unclosed cdata section"; break; 617cdf0e10cSrcweir case XML_ERROR_EXTERNAL_ENTITY_HANDLING: pMessage = "external entity reference"; break; 618cdf0e10cSrcweir case XML_ERROR_NOT_STANDALONE: pMessage = "not standalone"; break; 619cdf0e10cSrcweir default:; 620cdf0e10cSrcweir } 621cdf0e10cSrcweir 622cdf0e10cSrcweir OUStringBuffer aBuffer( sal_Unicode( '[' ) ); 623cdf0e10cSrcweir aBuffer.append( sSystemId ); 624cdf0e10cSrcweir aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " line " ) ); 625cdf0e10cSrcweir aBuffer.append( nLine ); 626cdf0e10cSrcweir aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "]: " ) ); 627cdf0e10cSrcweir aBuffer.appendAscii( pMessage ); 628cdf0e10cSrcweir aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " error" ) ); 629cdf0e10cSrcweir return aBuffer.makeStringAndClear(); 630cdf0e10cSrcweir } 631cdf0e10cSrcweir 632cdf0e10cSrcweir } // namespace 633cdf0e10cSrcweir 634cdf0e10cSrcweir // starts parsing with actual parser ! 635cdf0e10cSrcweir void FastSaxParser::parse() 636cdf0e10cSrcweir { 637cdf0e10cSrcweir const int BUFFER_SIZE = 16 * 1024; 638cdf0e10cSrcweir Sequence< sal_Int8 > seqOut( BUFFER_SIZE ); 639cdf0e10cSrcweir 640cdf0e10cSrcweir Entity& rEntity = getEntity(); 641cdf0e10cSrcweir int nRead = 0; 642cdf0e10cSrcweir do 643cdf0e10cSrcweir { 644cdf0e10cSrcweir nRead = rEntity.maConverter.readAndConvert( seqOut, BUFFER_SIZE ); 645cdf0e10cSrcweir if( nRead <= 0 ) 646cdf0e10cSrcweir { 647cdf0e10cSrcweir XML_Parse( rEntity.mpParser, (const char*) seqOut.getConstArray(), 0, 1 ); 648cdf0e10cSrcweir break; 649cdf0e10cSrcweir } 650cdf0e10cSrcweir 651cdf0e10cSrcweir bool bContinue = XML_Parse( rEntity.mpParser, (const char*) seqOut.getConstArray(), nRead, 0 ) != 0; 652cdf0e10cSrcweir // callbacks used inside XML_Parse may have caught an exception 653cdf0e10cSrcweir if( !bContinue || rEntity.maSavedException.hasValue() ) 654cdf0e10cSrcweir { 655cdf0e10cSrcweir // Error during parsing ! 656cdf0e10cSrcweir XML_Error xmlE = XML_GetErrorCode( rEntity.mpParser ); 657cdf0e10cSrcweir OUString sSystemId = mxDocumentLocator->getSystemId(); 658cdf0e10cSrcweir sal_Int32 nLine = mxDocumentLocator->getLineNumber(); 659cdf0e10cSrcweir 660cdf0e10cSrcweir SAXParseException aExcept( 661cdf0e10cSrcweir lclGetErrorMessage( xmlE, sSystemId, nLine ), 662cdf0e10cSrcweir Reference< XInterface >(), 663cdf0e10cSrcweir Any( &rEntity.maSavedException, getCppuType( &rEntity.maSavedException ) ), 664cdf0e10cSrcweir mxDocumentLocator->getPublicId(), 665cdf0e10cSrcweir mxDocumentLocator->getSystemId(), 666cdf0e10cSrcweir mxDocumentLocator->getLineNumber(), 667cdf0e10cSrcweir mxDocumentLocator->getColumnNumber() 668cdf0e10cSrcweir ); 669cdf0e10cSrcweir 670cdf0e10cSrcweir // error handler is set, it may throw the exception 671cdf0e10cSrcweir if( rEntity.mxErrorHandler.is() ) 672cdf0e10cSrcweir rEntity.mxErrorHandler->fatalError( Any( aExcept ) ); 673cdf0e10cSrcweir 674cdf0e10cSrcweir // error handler has not thrown, but parsing cannot go on, the 675cdf0e10cSrcweir // exception MUST be thrown 676cdf0e10cSrcweir throw aExcept; 677cdf0e10cSrcweir } 678cdf0e10cSrcweir } 679cdf0e10cSrcweir while( nRead > 0 ); 680cdf0e10cSrcweir } 681cdf0e10cSrcweir 682cdf0e10cSrcweir //------------------------------------------ 683cdf0e10cSrcweir // 684cdf0e10cSrcweir // The C-Callbacks 685cdf0e10cSrcweir // 686cdf0e10cSrcweir //----------------------------------------- 687cdf0e10cSrcweir 688cdf0e10cSrcweir namespace { 689cdf0e10cSrcweir 690cdf0e10cSrcweir struct AttributeData 691cdf0e10cSrcweir { 692cdf0e10cSrcweir OString maPrefix; 693cdf0e10cSrcweir OString maName; 694cdf0e10cSrcweir OString maValue; 695cdf0e10cSrcweir }; 696cdf0e10cSrcweir 697cdf0e10cSrcweir } // namespace 698cdf0e10cSrcweir 699cdf0e10cSrcweir void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char** awAttributes ) 700cdf0e10cSrcweir { 701cdf0e10cSrcweir Reference< XFastContextHandler > xParentContext; 702cdf0e10cSrcweir Entity& rEntity = getEntity(); 703cdf0e10cSrcweir if( !rEntity.maContextStack.empty() ) 704cdf0e10cSrcweir { 705cdf0e10cSrcweir xParentContext = rEntity.maContextStack.top()->mxContext; 706cdf0e10cSrcweir if( !xParentContext.is() ) 707cdf0e10cSrcweir { 708cdf0e10cSrcweir // we ignore current elements, so no processing needed 709cdf0e10cSrcweir pushContext(); 710cdf0e10cSrcweir return; 711cdf0e10cSrcweir } 712cdf0e10cSrcweir } 713cdf0e10cSrcweir 714cdf0e10cSrcweir pushContext(); 715cdf0e10cSrcweir 716cdf0e10cSrcweir rEntity.mxAttributes->clear(); 717cdf0e10cSrcweir 718cdf0e10cSrcweir // create attribute map and process namespace instructions 719cdf0e10cSrcweir int i = 0; 720cdf0e10cSrcweir sal_Int32 nNameLen, nPrefixLen; 721cdf0e10cSrcweir const XML_Char *pName; 722cdf0e10cSrcweir const XML_Char *pPrefix; 723cdf0e10cSrcweir 724cdf0e10cSrcweir try 725cdf0e10cSrcweir { 72649333635SJohn Bampton /* #158414# Each element may define new namespaces, also for attributes. 727cdf0e10cSrcweir First, process all namespace attributes and cache other attributes in a 728cdf0e10cSrcweir vector. Second, process the attributes after namespaces have been 729cdf0e10cSrcweir initialized. */ 730cdf0e10cSrcweir ::std::vector< AttributeData > aAttribs; 731cdf0e10cSrcweir 732cdf0e10cSrcweir // #158414# first: get namespaces 733cdf0e10cSrcweir for( ; awAttributes[i]; i += 2 ) 734cdf0e10cSrcweir { 735cdf0e10cSrcweir OSL_ASSERT( awAttributes[i+1] ); 736cdf0e10cSrcweir 737cdf0e10cSrcweir splitName( awAttributes[i], pPrefix, nPrefixLen, pName, nNameLen ); 738cdf0e10cSrcweir if( nPrefixLen ) 739cdf0e10cSrcweir { 740cdf0e10cSrcweir if( (nPrefixLen == 5) && (strncmp( pPrefix, "xmlns", 5 ) == 0) ) 741cdf0e10cSrcweir { 742cdf0e10cSrcweir DefineNamespace( OString( pName, nNameLen ), awAttributes[i+1] ); 743cdf0e10cSrcweir } 744cdf0e10cSrcweir else 745cdf0e10cSrcweir { 746cdf0e10cSrcweir aAttribs.resize( aAttribs.size() + 1 ); 747cdf0e10cSrcweir aAttribs.back().maPrefix = OString( pPrefix, nPrefixLen ); 748cdf0e10cSrcweir aAttribs.back().maName = OString( pName, nNameLen ); 749cdf0e10cSrcweir aAttribs.back().maValue = OString( awAttributes[i+1] ); 750cdf0e10cSrcweir } 751cdf0e10cSrcweir } 752cdf0e10cSrcweir else 753cdf0e10cSrcweir { 754cdf0e10cSrcweir if( (nNameLen == 5) && (strcmp( pName, "xmlns" ) == 0) ) 755cdf0e10cSrcweir { 756cdf0e10cSrcweir // namespace of the element found 757cdf0e10cSrcweir rEntity.maContextStack.top()->maNamespace = OUString( awAttributes[i+1], strlen( awAttributes[i+1] ), RTL_TEXTENCODING_UTF8 ); 758cdf0e10cSrcweir } 759cdf0e10cSrcweir else 760cdf0e10cSrcweir { 761cdf0e10cSrcweir aAttribs.resize( aAttribs.size() + 1 ); 762cdf0e10cSrcweir aAttribs.back().maName = OString( pName, nNameLen ); 763cdf0e10cSrcweir aAttribs.back().maValue = OString( awAttributes[i+1] ); 764cdf0e10cSrcweir } 765cdf0e10cSrcweir } 766cdf0e10cSrcweir } 767cdf0e10cSrcweir 768cdf0e10cSrcweir // #158414# second: fill attribute list with other attributes 769cdf0e10cSrcweir for( ::std::vector< AttributeData >::const_iterator aIt = aAttribs.begin(), aEnd = aAttribs.end(); aIt != aEnd; ++aIt ) 770cdf0e10cSrcweir { 771cdf0e10cSrcweir if( aIt->maPrefix.getLength() > 0 ) 772cdf0e10cSrcweir { 773cdf0e10cSrcweir sal_Int32 nAttributeToken = GetTokenWithPrefix( aIt->maPrefix, aIt->maName ); 774cdf0e10cSrcweir if( nAttributeToken != FastToken::DONTKNOW ) 775cdf0e10cSrcweir rEntity.mxAttributes->add( nAttributeToken, aIt->maValue ); 776cdf0e10cSrcweir else 777cdf0e10cSrcweir rEntity.mxAttributes->addUnknown( GetNamespaceURL( aIt->maPrefix ), aIt->maName, aIt->maValue ); 778cdf0e10cSrcweir } 779cdf0e10cSrcweir else 780cdf0e10cSrcweir { 781cdf0e10cSrcweir sal_Int32 nAttributeToken = GetToken( aIt->maName ); 782cdf0e10cSrcweir if( nAttributeToken != FastToken::DONTKNOW ) 783cdf0e10cSrcweir rEntity.mxAttributes->add( nAttributeToken, aIt->maValue ); 784cdf0e10cSrcweir else 785cdf0e10cSrcweir rEntity.mxAttributes->addUnknown( aIt->maName, aIt->maValue ); 786cdf0e10cSrcweir } 787cdf0e10cSrcweir } 788cdf0e10cSrcweir 789cdf0e10cSrcweir sal_Int32 nElementToken; 790cdf0e10cSrcweir splitName( pwName, pPrefix, nPrefixLen, pName, nNameLen ); 791cdf0e10cSrcweir if( nPrefixLen > 0 ) 792cdf0e10cSrcweir nElementToken = GetTokenWithPrefix( pPrefix, nPrefixLen, pName, nNameLen ); 793cdf0e10cSrcweir else if( rEntity.maContextStack.top()->maNamespace.getLength() > 0 ) 794cdf0e10cSrcweir nElementToken = GetTokenWithNamespaceURL( rEntity.maContextStack.top()->maNamespace, pName, nNameLen ); 795cdf0e10cSrcweir else 796cdf0e10cSrcweir nElementToken = GetToken( pName ); 797cdf0e10cSrcweir rEntity.maContextStack.top()->mnElementToken = nElementToken; 798cdf0e10cSrcweir 799cdf0e10cSrcweir Reference< XFastAttributeList > xAttr( rEntity.mxAttributes.get() ); 800cdf0e10cSrcweir Reference< XFastContextHandler > xContext; 801cdf0e10cSrcweir if( nElementToken == FastToken::DONTKNOW ) 802cdf0e10cSrcweir { 803cdf0e10cSrcweir if( nPrefixLen > 0 ) 804cdf0e10cSrcweir rEntity.maContextStack.top()->maNamespace = GetNamespaceURL( pPrefix, nPrefixLen ); 805cdf0e10cSrcweir 806cdf0e10cSrcweir const OUString aNamespace( rEntity.maContextStack.top()->maNamespace ); 807cdf0e10cSrcweir const OUString aElementName( pPrefix, nPrefixLen, RTL_TEXTENCODING_UTF8 ); 808cdf0e10cSrcweir rEntity.maContextStack.top()->maElementName = aElementName; 809cdf0e10cSrcweir 810cdf0e10cSrcweir if( xParentContext.is() ) 811cdf0e10cSrcweir xContext = xParentContext->createUnknownChildContext( aNamespace, aElementName, xAttr ); 812cdf0e10cSrcweir else 813cdf0e10cSrcweir xContext = rEntity.mxDocumentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr ); 814cdf0e10cSrcweir 815cdf0e10cSrcweir if( xContext.is() ) 816cdf0e10cSrcweir { 817cdf0e10cSrcweir rEntity.maContextStack.top()->mxContext = xContext; 818cdf0e10cSrcweir xContext->startUnknownElement( aNamespace, aElementName, xAttr ); 819cdf0e10cSrcweir } 820cdf0e10cSrcweir } 821cdf0e10cSrcweir else 822cdf0e10cSrcweir { 823cdf0e10cSrcweir if( xParentContext.is() ) 824cdf0e10cSrcweir xContext = xParentContext->createFastChildContext( nElementToken, xAttr ); 825cdf0e10cSrcweir else 826cdf0e10cSrcweir xContext = rEntity.mxDocumentHandler->createFastChildContext( nElementToken, xAttr ); 827cdf0e10cSrcweir 828cdf0e10cSrcweir 829cdf0e10cSrcweir if( xContext.is() ) 830cdf0e10cSrcweir { 831cdf0e10cSrcweir rEntity.maContextStack.top()->mxContext = xContext; 832cdf0e10cSrcweir xContext->startFastElement( nElementToken, xAttr ); 833cdf0e10cSrcweir } 834cdf0e10cSrcweir } 835cdf0e10cSrcweir } 836cdf0e10cSrcweir catch( Exception& e ) 837cdf0e10cSrcweir { 838cdf0e10cSrcweir rEntity.maSavedException <<= e; 839cdf0e10cSrcweir } 840cdf0e10cSrcweir } 841cdf0e10cSrcweir 842cdf0e10cSrcweir void FastSaxParser::callbackEndElement( const XML_Char* ) 843cdf0e10cSrcweir { 844cdf0e10cSrcweir Entity& rEntity = getEntity(); 845cdf0e10cSrcweir OSL_ENSURE( !rEntity.maContextStack.empty(), "FastSaxParser::callbackEndElement - no context" ); 846cdf0e10cSrcweir if( !rEntity.maContextStack.empty() ) 847cdf0e10cSrcweir { 848cdf0e10cSrcweir SaxContextImplPtr pContext = rEntity.maContextStack.top(); 849cdf0e10cSrcweir const Reference< XFastContextHandler >& xContext( pContext->mxContext ); 850cdf0e10cSrcweir if( xContext.is() ) try 851cdf0e10cSrcweir { 852cdf0e10cSrcweir sal_Int32 nElementToken = pContext->mnElementToken; 853cdf0e10cSrcweir if( nElementToken != FastToken::DONTKNOW ) 854cdf0e10cSrcweir xContext->endFastElement( nElementToken ); 855cdf0e10cSrcweir else 856cdf0e10cSrcweir xContext->endUnknownElement( pContext->maNamespace, pContext->maElementName ); 857cdf0e10cSrcweir } 858cdf0e10cSrcweir catch( Exception& e ) 859cdf0e10cSrcweir { 860cdf0e10cSrcweir rEntity.maSavedException <<= e; 861cdf0e10cSrcweir } 862cdf0e10cSrcweir 863cdf0e10cSrcweir popContext(); 864cdf0e10cSrcweir } 865cdf0e10cSrcweir } 866cdf0e10cSrcweir 867cdf0e10cSrcweir 868cdf0e10cSrcweir void FastSaxParser::callbackCharacters( const XML_Char* s, int nLen ) 869cdf0e10cSrcweir { 870cdf0e10cSrcweir Entity& rEntity = getEntity(); 871cdf0e10cSrcweir const Reference< XFastContextHandler >& xContext( rEntity.maContextStack.top()->mxContext ); 872cdf0e10cSrcweir if( xContext.is() ) try 873cdf0e10cSrcweir { 874cdf0e10cSrcweir xContext->characters( OUString( s, nLen, RTL_TEXTENCODING_UTF8 ) ); 875cdf0e10cSrcweir } 876cdf0e10cSrcweir catch( Exception& e ) 877cdf0e10cSrcweir { 878cdf0e10cSrcweir rEntity.maSavedException <<= e; 879cdf0e10cSrcweir } 880cdf0e10cSrcweir } 881cdf0e10cSrcweir 882cdf0e10cSrcweir int FastSaxParser::callbackExternalEntityRef( XML_Parser parser, 883cdf0e10cSrcweir const XML_Char *context, const XML_Char * /*base*/, const XML_Char *systemId, const XML_Char *publicId ) 884cdf0e10cSrcweir { 885cdf0e10cSrcweir bool bOK = true; 886cdf0e10cSrcweir InputSource source; 887cdf0e10cSrcweir 888cdf0e10cSrcweir Entity& rCurrEntity = getEntity(); 889cdf0e10cSrcweir Entity aNewEntity( rCurrEntity ); 890cdf0e10cSrcweir 891cdf0e10cSrcweir if( rCurrEntity.mxEntityResolver.is() ) try 892cdf0e10cSrcweir { 893cdf0e10cSrcweir aNewEntity.maStructSource = rCurrEntity.mxEntityResolver->resolveEntity( 894cdf0e10cSrcweir OUString( publicId, strlen( publicId ), RTL_TEXTENCODING_UTF8 ) , 895cdf0e10cSrcweir OUString( systemId, strlen( systemId ), RTL_TEXTENCODING_UTF8 ) ); 896cdf0e10cSrcweir } 897cdf0e10cSrcweir catch( SAXParseException & e ) 898cdf0e10cSrcweir { 899cdf0e10cSrcweir rCurrEntity.maSavedException <<= e; 900cdf0e10cSrcweir bOK = false; 901cdf0e10cSrcweir } 902cdf0e10cSrcweir catch( SAXException & e ) 903cdf0e10cSrcweir { 904cdf0e10cSrcweir rCurrEntity.maSavedException <<= SAXParseException( 905cdf0e10cSrcweir e.Message, e.Context, e.WrappedException, 906cdf0e10cSrcweir mxDocumentLocator->getPublicId(), 907cdf0e10cSrcweir mxDocumentLocator->getSystemId(), 908cdf0e10cSrcweir mxDocumentLocator->getLineNumber(), 909cdf0e10cSrcweir mxDocumentLocator->getColumnNumber() ); 910cdf0e10cSrcweir bOK = false; 911cdf0e10cSrcweir } 912cdf0e10cSrcweir 913cdf0e10cSrcweir if( aNewEntity.maStructSource.aInputStream.is() ) 914cdf0e10cSrcweir { 915cdf0e10cSrcweir aNewEntity.mpParser = XML_ExternalEntityParserCreate( parser, context, 0 ); 916cdf0e10cSrcweir if( !aNewEntity.mpParser ) 917cdf0e10cSrcweir { 918cdf0e10cSrcweir return false; 919cdf0e10cSrcweir } 920cdf0e10cSrcweir 921cdf0e10cSrcweir aNewEntity.maConverter.setInputStream( aNewEntity.maStructSource.aInputStream ); 922cdf0e10cSrcweir pushEntity( aNewEntity ); 923cdf0e10cSrcweir try 924cdf0e10cSrcweir { 925cdf0e10cSrcweir parse(); 926cdf0e10cSrcweir } 927cdf0e10cSrcweir catch( SAXParseException & e ) 928cdf0e10cSrcweir { 929cdf0e10cSrcweir rCurrEntity.maSavedException <<= e; 930cdf0e10cSrcweir bOK = false; 931cdf0e10cSrcweir } 932cdf0e10cSrcweir catch( IOException &e ) 933cdf0e10cSrcweir { 934cdf0e10cSrcweir SAXException aEx; 935cdf0e10cSrcweir aEx.WrappedException <<= e; 936cdf0e10cSrcweir rCurrEntity.maSavedException <<= aEx; 937cdf0e10cSrcweir bOK = false; 938cdf0e10cSrcweir } 939cdf0e10cSrcweir catch( RuntimeException &e ) 940cdf0e10cSrcweir { 941cdf0e10cSrcweir SAXException aEx; 942cdf0e10cSrcweir aEx.WrappedException <<= e; 943cdf0e10cSrcweir rCurrEntity.maSavedException <<= aEx; 944cdf0e10cSrcweir bOK = false; 945cdf0e10cSrcweir } 946cdf0e10cSrcweir 947cdf0e10cSrcweir popEntity(); 948cdf0e10cSrcweir XML_ParserFree( aNewEntity.mpParser ); 949cdf0e10cSrcweir } 950cdf0e10cSrcweir 951cdf0e10cSrcweir return bOK; 952cdf0e10cSrcweir } 953cdf0e10cSrcweir 954cdf0e10cSrcweir } // namespace sax_fastparser 955