1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski #ifndef _SAX_FASTPARSER_HXX_ 25*b1cdbd2cSJim Jagielski #define _SAX_FASTPARSER_HXX_ 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski #include <vector> 28*b1cdbd2cSJim Jagielski #include <stack> 29*b1cdbd2cSJim Jagielski #include <hash_map> 30*b1cdbd2cSJim Jagielski #include <boost/shared_ptr.hpp> 31*b1cdbd2cSJim Jagielski #include <rtl/ref.hxx> 32*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/sax/XFastParser.hpp> 33*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/sax/XFastTokenHandler.hpp> 34*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/sax/XFastDocumentHandler.hpp> 35*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XServiceInfo.hpp> 36*b1cdbd2cSJim Jagielski #include <cppuhelper/implbase2.hxx> 37*b1cdbd2cSJim Jagielski 38*b1cdbd2cSJim Jagielski #include <expat.h> 39*b1cdbd2cSJim Jagielski #include "xml2utf.hxx" 40*b1cdbd2cSJim Jagielski 41*b1cdbd2cSJim Jagielski #include <sax/fastattribs.hxx> 42*b1cdbd2cSJim Jagielski 43*b1cdbd2cSJim Jagielski #define PARSER_IMPLEMENTATION_NAME "com.sun.star.comp.extensions.xml.sax.FastParser" 44*b1cdbd2cSJim Jagielski #define PARSER_SERVICE_NAME "com.sun.star.xml.sax.FastParser" 45*b1cdbd2cSJim Jagielski 46*b1cdbd2cSJim Jagielski namespace sax_fastparser { 47*b1cdbd2cSJim Jagielski 48*b1cdbd2cSJim Jagielski class FastLocatorImpl; 49*b1cdbd2cSJim Jagielski struct NamespaceDefine; 50*b1cdbd2cSJim Jagielski struct SaxContextImpl; 51*b1cdbd2cSJim Jagielski 52*b1cdbd2cSJim Jagielski typedef ::boost::shared_ptr< SaxContextImpl > SaxContextImplPtr; 53*b1cdbd2cSJim Jagielski typedef ::boost::shared_ptr< NamespaceDefine > NamespaceDefineRef; 54*b1cdbd2cSJim Jagielski 55*b1cdbd2cSJim Jagielski typedef ::std::hash_map< ::rtl::OUString, sal_Int32, 56*b1cdbd2cSJim Jagielski ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > NamespaceMap; 57*b1cdbd2cSJim Jagielski 58*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------- 59*b1cdbd2cSJim Jagielski 60*b1cdbd2cSJim Jagielski struct ParserData 61*b1cdbd2cSJim Jagielski { 62*b1cdbd2cSJim Jagielski ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastDocumentHandler > mxDocumentHandler; 63*b1cdbd2cSJim Jagielski ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxTokenHandler; 64*b1cdbd2cSJim Jagielski ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XErrorHandler > mxErrorHandler; 65*b1cdbd2cSJim Jagielski ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XEntityResolver > mxEntityResolver; 66*b1cdbd2cSJim Jagielski ::com::sun::star::lang::Locale maLocale; 67*b1cdbd2cSJim Jagielski 68*b1cdbd2cSJim Jagielski ParserData(); 69*b1cdbd2cSJim Jagielski ~ParserData(); 70*b1cdbd2cSJim Jagielski }; 71*b1cdbd2cSJim Jagielski 72*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------- 73*b1cdbd2cSJim Jagielski 74*b1cdbd2cSJim Jagielski // Entity binds all information needed for a single file 75*b1cdbd2cSJim Jagielski struct Entity : public ParserData 76*b1cdbd2cSJim Jagielski { 77*b1cdbd2cSJim Jagielski ::com::sun::star::xml::sax::InputSource maStructSource; 78*b1cdbd2cSJim Jagielski XML_Parser mpParser; 79*b1cdbd2cSJim Jagielski ::sax_expatwrap::XMLFile2UTFConverter maConverter; 80*b1cdbd2cSJim Jagielski ::rtl::Reference< FastAttributeList > mxAttributes; 81*b1cdbd2cSJim Jagielski 82*b1cdbd2cSJim Jagielski // Exceptions cannot be thrown through the C-XmlParser (possible resource leaks), 83*b1cdbd2cSJim Jagielski // therefore the exception must be saved somewhere. 84*b1cdbd2cSJim Jagielski ::com::sun::star::uno::Any maSavedException; 85*b1cdbd2cSJim Jagielski 86*b1cdbd2cSJim Jagielski ::std::stack< SaxContextImplPtr > maContextStack; 87*b1cdbd2cSJim Jagielski ::std::vector< NamespaceDefineRef > maNamespaceDefines; 88*b1cdbd2cSJim Jagielski 89*b1cdbd2cSJim Jagielski explicit Entity( const ParserData& rData ); 90*b1cdbd2cSJim Jagielski ~Entity(); 91*b1cdbd2cSJim Jagielski }; 92*b1cdbd2cSJim Jagielski 93*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------- 94*b1cdbd2cSJim Jagielski 95*b1cdbd2cSJim Jagielski // This class implements the external Parser interface 96*b1cdbd2cSJim Jagielski class FastSaxParser : public ::cppu::WeakImplHelper2< ::com::sun::star::xml::sax::XFastParser, ::com::sun::star::lang::XServiceInfo > 97*b1cdbd2cSJim Jagielski { 98*b1cdbd2cSJim Jagielski public: 99*b1cdbd2cSJim Jagielski FastSaxParser(); 100*b1cdbd2cSJim Jagielski virtual ~FastSaxParser(); 101*b1cdbd2cSJim Jagielski 102*b1cdbd2cSJim Jagielski // The implementation details 103*b1cdbd2cSJim Jagielski static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(void); 104*b1cdbd2cSJim Jagielski 105*b1cdbd2cSJim Jagielski // XFastParser 106*b1cdbd2cSJim Jagielski virtual void SAL_CALL parseStream( const ::com::sun::star::xml::sax::InputSource& aInputSource ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); 107*b1cdbd2cSJim Jagielski virtual void SAL_CALL setFastDocumentHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastDocumentHandler >& Handler ) throw (::com::sun::star::uno::RuntimeException); 108*b1cdbd2cSJim Jagielski virtual void SAL_CALL setTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& Handler ) throw (::com::sun::star::uno::RuntimeException); 109*b1cdbd2cSJim Jagielski virtual void SAL_CALL registerNamespace( const ::rtl::OUString& NamespaceURL, sal_Int32 NamespaceToken ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); 110*b1cdbd2cSJim Jagielski virtual void SAL_CALL setErrorHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XErrorHandler >& Handler ) throw (::com::sun::star::uno::RuntimeException); 111*b1cdbd2cSJim Jagielski virtual void SAL_CALL setEntityResolver( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XEntityResolver >& Resolver ) throw (::com::sun::star::uno::RuntimeException); 112*b1cdbd2cSJim Jagielski virtual void SAL_CALL setLocale( const ::com::sun::star::lang::Locale& rLocale ) throw (::com::sun::star::uno::RuntimeException); 113*b1cdbd2cSJim Jagielski 114*b1cdbd2cSJim Jagielski // XServiceInfo 115*b1cdbd2cSJim Jagielski virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException); 116*b1cdbd2cSJim Jagielski virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); 117*b1cdbd2cSJim Jagielski virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException); 118*b1cdbd2cSJim Jagielski 119*b1cdbd2cSJim Jagielski // called by the C callbacks of the expat parser 120*b1cdbd2cSJim Jagielski void callbackStartElement( const XML_Char* name, const XML_Char** atts ); 121*b1cdbd2cSJim Jagielski void callbackEndElement( const XML_Char* name ); 122*b1cdbd2cSJim Jagielski void callbackCharacters( const XML_Char* s, int nLen ); 123*b1cdbd2cSJim Jagielski int callbackExternalEntityRef( XML_Parser parser, const XML_Char *openEntityNames, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); 124*b1cdbd2cSJim Jagielski pushEntity(const Entity & rEntity)125*b1cdbd2cSJim Jagielski inline void pushEntity( const Entity& rEntity ) { maEntities.push( rEntity ); } popEntity()126*b1cdbd2cSJim Jagielski inline void popEntity() { maEntities.pop(); } getEntity()127*b1cdbd2cSJim Jagielski Entity& getEntity() { return maEntities.top(); } 128*b1cdbd2cSJim Jagielski 129*b1cdbd2cSJim Jagielski private: 130*b1cdbd2cSJim Jagielski void parse(); 131*b1cdbd2cSJim Jagielski 132*b1cdbd2cSJim Jagielski sal_Int32 GetToken( const ::rtl::OString& rToken ); 133*b1cdbd2cSJim Jagielski sal_Int32 GetToken( const sal_Char* pToken, sal_Int32 nTokenLen = 0 ); 134*b1cdbd2cSJim Jagielski sal_Int32 GetTokenWithPrefix( const ::rtl::OString& rPrefix, const ::rtl::OString& rName ) throw (::com::sun::star::xml::sax::SAXException); 135*b1cdbd2cSJim Jagielski sal_Int32 GetTokenWithPrefix( const sal_Char*pPrefix, int nPrefixLen, const sal_Char* pName, int nNameLen ) throw (::com::sun::star::xml::sax::SAXException); 136*b1cdbd2cSJim Jagielski ::rtl::OUString GetNamespaceURL( const ::rtl::OString& rPrefix ) throw (::com::sun::star::xml::sax::SAXException); 137*b1cdbd2cSJim Jagielski ::rtl::OUString GetNamespaceURL( const sal_Char*pPrefix, int nPrefixLen ) throw (::com::sun::star::xml::sax::SAXException); 138*b1cdbd2cSJim Jagielski sal_Int32 GetNamespaceToken( const ::rtl::OUString& rNamespaceURL ); 139*b1cdbd2cSJim Jagielski sal_Int32 GetTokenWithNamespaceURL( const ::rtl::OUString& rNamespaceURL, const sal_Char* pName, int nNameLen ); 140*b1cdbd2cSJim Jagielski void DefineNamespace( const ::rtl::OString& rPrefix, const sal_Char* pNamespaceURL ); 141*b1cdbd2cSJim Jagielski sal_Int32 CreateCustomToken( const sal_Char* pToken, int len = 0 ); 142*b1cdbd2cSJim Jagielski 143*b1cdbd2cSJim Jagielski void pushContext(); 144*b1cdbd2cSJim Jagielski void popContext(); 145*b1cdbd2cSJim Jagielski 146*b1cdbd2cSJim Jagielski void splitName( const XML_Char *pwName, const XML_Char *&rpPrefix, sal_Int32 &rPrefixLen, const XML_Char *&rpName, sal_Int32 &rNameLen ); 147*b1cdbd2cSJim Jagielski 148*b1cdbd2cSJim Jagielski private: 149*b1cdbd2cSJim Jagielski ::osl::Mutex maMutex; 150*b1cdbd2cSJim Jagielski 151*b1cdbd2cSJim Jagielski ::rtl::Reference< FastLocatorImpl > mxDocumentLocator; 152*b1cdbd2cSJim Jagielski NamespaceMap maNamespaceMap; 153*b1cdbd2cSJim Jagielski 154*b1cdbd2cSJim Jagielski ParserData maData; /// Cached parser configuration for next call of parseStream(). 155*b1cdbd2cSJim Jagielski ::std::stack< Entity > maEntities; /// Entity stack for each call of parseStream(). 156*b1cdbd2cSJim Jagielski }; 157*b1cdbd2cSJim Jagielski 158*b1cdbd2cSJim Jagielski } 159*b1cdbd2cSJim Jagielski 160*b1cdbd2cSJim Jagielski #endif // _SAX_FASTPARSER_HXX_ 161