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