diff options
Diffstat (limited to 'sax')
-rw-r--r-- | sax/inc/sax/fastattribs.hxx (renamed from sax/source/fastparser/fastattribs.hxx) | 18 | ||||
-rw-r--r-- | sax/inc/sax/fshelper.hxx | 115 | ||||
-rw-r--r-- | sax/prj/build.lst | 1 | ||||
-rw-r--r-- | sax/prj/d.lst | 2 | ||||
-rw-r--r-- | sax/source/fastparser/facreg.cxx | 106 | ||||
-rw-r--r-- | sax/source/fastparser/fastparser.cxx | 218 | ||||
-rw-r--r-- | sax/source/fastparser/fastparser.hxx | 163 | ||||
-rw-r--r-- | sax/source/fastparser/makefile.mk | 6 | ||||
-rw-r--r-- | sax/source/tools/fastattribs.cxx (renamed from sax/source/fastparser/fastattribs.cxx) | 61 | ||||
-rw-r--r-- | sax/source/tools/fastserializer.cxx | 388 | ||||
-rw-r--r-- | sax/source/tools/fastserializer.hxx | 147 | ||||
-rw-r--r-- | sax/source/tools/fshelper.cxx | 195 | ||||
-rw-r--r-- | sax/source/tools/makefile.mk | 27 |
13 files changed, 1201 insertions, 246 deletions
diff --git a/sax/source/fastparser/fastattribs.hxx b/sax/inc/sax/fastattribs.hxx index 15c8d6920f07..e7c42c55bafd 100644 --- a/sax/source/fastparser/fastattribs.hxx +++ b/sax/inc/sax/fastattribs.hxx @@ -34,8 +34,10 @@ #include <com/sun/star/xml/sax/XFastAttributeList.hpp> #include <com/sun/star/xml/sax/XFastTokenHandler.hpp> #include <com/sun/star/xml/Attribute.hpp> +#include <com/sun/star/xml/FastAttribute.hpp> #include <cppuhelper/implbase1.hxx> +#include "sax/dllapi.h" #include <map> #include <vector> @@ -43,12 +45,23 @@ namespace sax_fastparser { -struct UnknownAttribute; +struct UnknownAttribute +{ + ::rtl::OUString maNamespaceURL; + ::rtl::OString maName; + ::rtl::OString maValue; + + UnknownAttribute( const ::rtl::OUString& rNamespaceURL, const ::rtl::OString& rName, const ::rtl::OString& rValue ); + + UnknownAttribute( const ::rtl::OString& rName, const ::rtl::OString& rValue ); + + void FillAttribute( ::com::sun::star::xml::Attribute* pAttrib ) const; +}; typedef std::map< sal_Int32, ::rtl::OString > FastAttributeMap; typedef std::vector< UnknownAttribute > UnknownAttributeList; -class FastAttributeList : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastAttributeList > +class SAX_DLLPUBLIC FastAttributeList : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastAttributeList > { public: FastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xTokenHandler ); @@ -66,6 +79,7 @@ public: virtual ::rtl::OUString SAL_CALL getValue( ::sal_Int32 Token ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getOptionalValue( ::sal_Int32 Token ) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::com::sun::star::xml::Attribute > SAL_CALL getUnknownAttributes( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::xml::FastAttribute > SAL_CALL getFastAttributes() throw (::com::sun::star::uno::RuntimeException); private: FastAttributeMap maAttributes; diff --git a/sax/inc/sax/fshelper.hxx b/sax/inc/sax/fshelper.hxx new file mode 100644 index 000000000000..b1ce4ba39d1b --- /dev/null +++ b/sax/inc/sax/fshelper.hxx @@ -0,0 +1,115 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SAX_FS_HELPER_HXX_ +#define _SAX_FS_HELPER_HXX_ + +#include <com/sun/star/uno/XReference.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/xml/sax/XFastTokenHandler.hpp> +#include <stdarg.h> +#include <boost/shared_ptr.hpp> +#include <sax/fastattribs.hxx> +#include "sax/dllapi.h" + +#define FSNS(namespace, element) ((namespace << 16) | element) +#define FSEND -1 // same as XML_TOKEN_INVALID + +namespace sax_fastparser { + +typedef ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList > XFastAttributeListRef; + +class FastSaxSerializer; + +class SAX_DLLPUBLIC FastSerializerHelper +{ +public: + + FastSerializerHelper( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream ); + + ~FastSerializerHelper(); + + void startElement(const char* elementName, ...); + void singleElement(const char* elementName, ...); + void endElement(const char* elementName); + + void startElementV(sal_Int32 elementTokenId, va_list args); + void singleElementV(sal_Int32 elementTokenId, va_list args); + + inline void startElement(sal_Int32 elementTokenId, ...) + { va_list args; va_start( args, elementTokenId ); startElementV( elementTokenId, args ); va_end( args ); } + inline void singleElement(sal_Int32 elementTokenId, ...) + { va_list args; va_start( args, elementTokenId ); singleElementV( elementTokenId, args ); va_end( args ); } + inline void startElementNS(sal_Int32 namespaceTokenId, sal_Int32 elementTokenId, ...) + { va_list args; va_start( args, elementTokenId ); startElementV( FSNS( namespaceTokenId, elementTokenId), args ); va_end( args ); } + inline void singleElementNS(sal_Int32 namespaceTokenId, sal_Int32 elementTokenId, ...) + { va_list args; va_start( args, elementTokenId ); singleElementV( FSNS( namespaceTokenId, elementTokenId), args ); va_end( args ); } + void endElement(sal_Int32 elementTokenId); + inline void endElementNS(sal_Int32 namespaceTokenId, sal_Int32 elementTokenId) + { endElement( FSNS( namespaceTokenId, elementTokenId ) ); } + + void singleElement(const char* elementName, XFastAttributeListRef xAttrList); + inline void singleElement(sal_Int32 elementTokenId, XFastAttributeListRef xAttrList) + { singleElementV(elementTokenId, xAttrList); } + void singleElementV(sal_Int32 elementTokenId, XFastAttributeListRef xAttrList); + inline void singleElementNS(sal_Int32 namespaceTokenId, sal_Int32 elementTokenId, XFastAttributeListRef xAttrList) + { singleElementV(FSNS( namespaceTokenId, elementTokenId), xAttrList); } + + FastSerializerHelper* write(const char* value); + FastSerializerHelper* write(const rtl::OUString& value); + FastSerializerHelper* write(sal_Int32 value); + FastSerializerHelper* write(sal_Int64 value); + FastSerializerHelper* write(float value); + FastSerializerHelper* write(double value); + + FastSerializerHelper* writeEscaped(const char* value); + FastSerializerHelper* writeEscaped(const rtl::OUString& value); + + FastSerializerHelper* writeId(sal_Int32 tokenId); + + ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > getOutputStream(); + + FastAttributeList *createAttrList(); + + void mark(); + void mergeTopMarks( bool bPrepend = false ); + +private: + + FastSaxSerializer* mpSerializer; + com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastTokenHandler> mxTokenHandler; + +}; + +typedef boost::shared_ptr< FastSerializerHelper > FSHelperPtr; + +} + +#endif // _SAX_FS_HELPER_HXX_ diff --git a/sax/prj/build.lst b/sax/prj/build.lst index 9cc88467d011..e3f70c484610 100644 --- a/sax/prj/build.lst +++ b/sax/prj/build.lst @@ -3,4 +3,3 @@ ax sax usr1 - all ax_mkout NULL ax sax\source\expatwrap nmake - all ax_expatwrap NULL ax sax\source\tools nmake - all ax_tools NULL ax sax\source\fastparser nmake - all ax_fastparser ax_expatwrap ax_tools NULL -ax sax\util nmake - all ax_util ax_expatwrap ax_tools ax_fastparser NULL diff --git a/sax/prj/d.lst b/sax/prj/d.lst index 3cffb18fe1f6..87f01348163c 100644 --- a/sax/prj/d.lst +++ b/sax/prj/d.lst @@ -6,6 +6,8 @@ mkdir: %_DEST%\inc%_EXT%\sax mkdir: %_DEST%\inc%_EXT%\sax\tools ..\inc\sax\dllapi.h %_DEST%\inc%_EXT%\sax\dllapi.h +..\inc\sax\fshelper.hxx %_DEST%\inc%_EXT%\sax\fshelper.hxx +..\inc\sax\fastattribs.hxx %_DEST%\inc%_EXT%\sax\fastattribs.hxx ..\inc\sax\tools\converter.hxx %_DEST%\inc%_EXT%\sax\tools\converter.hxx dos: sh -c "if test %OS% = MACOSX; then macosx-create-bundle %_DEST%\lib%_EXT%\*.dylib; fi" diff --git a/sax/source/fastparser/facreg.cxx b/sax/source/fastparser/facreg.cxx new file mode 100644 index 000000000000..1916a9740f1a --- /dev/null +++ b/sax/source/fastparser/facreg.cxx @@ -0,0 +1,106 @@ +#include <cppuhelper/factory.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/implbase2.hxx> + +#include "../tools/fastserializer.hxx" +#include "fastparser.hxx" + +using namespace sax_fastparser; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::registry; +using ::rtl::OUString; +using namespace ::com::sun::star::lang; + +namespace sax_fastparser +{ + +//-------------------------------------- +// the extern interface +//--------------------------------------- +Reference< XInterface > SAL_CALL FastSaxParser_CreateInstance( const Reference< XMultiServiceFactory > & ) throw(Exception) +{ + FastSaxParser *p = new FastSaxParser; + return Reference< XInterface > ( (OWeakObject * ) p ); +} + +Reference< XInterface > SAL_CALL FastSaxSerializer_CreateInstance( const Reference< XMultiServiceFactory > & ) throw(Exception) +{ + FastSaxSerializer *p = new FastSaxSerializer; + return Reference< XInterface > ( (OWeakObject * ) p ); +} +} + +extern "C" +{ + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + + +sal_Bool SAL_CALL component_writeInfo( + void * /*pServiceManager*/, void * pRegistryKey ) +{ + if (pRegistryKey) + { + try + { + Reference< XRegistryKey > xKey( reinterpret_cast< XRegistryKey * >( pRegistryKey ) ); + + Reference< XRegistryKey > xNewKey( xKey->createKey( + OUString::createFromAscii( "/" PARSER_IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) ); + xNewKey->createKey( OUString::createFromAscii( PARSER_SERVICE_NAME ) ); + + Reference< XRegistryKey > xNewKey1( xKey->createKey( + OUString::createFromAscii( "/" SERIALIZER_IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) ); + xNewKey1->createKey( OUString::createFromAscii( SERIALIZER_SERVICE_NAME ) ); + + return sal_True; + } + catch (InvalidRegistryException &) + { + OSL_ENSURE( sal_False, "### InvalidRegistryException!" ); + } + } + return sal_False; +} + +void * SAL_CALL component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ ) +{ + void * pRet = 0; + + if (pServiceManager ) + { + Reference< XSingleServiceFactory > xRet; + Reference< XMultiServiceFactory > xSMgr( reinterpret_cast< XMultiServiceFactory * > ( pServiceManager ) ); + + OUString aImplementationName( OUString::createFromAscii( pImplName ) ); + + if (aImplementationName == OUString( RTL_CONSTASCII_USTRINGPARAM( PARSER_IMPLEMENTATION_NAME ) ) ) + { + xRet = createSingleFactory( xSMgr, aImplementationName, + FastSaxParser_CreateInstance, + FastSaxParser::getSupportedServiceNames_Static() ); + } + else if (aImplementationName == OUString( RTL_CONSTASCII_USTRINGPARAM( SERIALIZER_IMPLEMENTATION_NAME ) ) ) + { + xRet = createSingleFactory( xSMgr, aImplementationName, + FastSaxSerializer_CreateInstance, + FastSaxSerializer::getSupportedServiceNames_Static() ); + } + + if (xRet.is()) + { + xRet->acquire(); + pRet = xRet.get(); + } + } + + return pRet; +} + + +} diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx index 8cf48649c8e4..2b2461c1173f 100644 --- a/sax/source/fastparser/fastparser.cxx +++ b/sax/source/fastparser/fastparser.cxx @@ -31,35 +31,17 @@ //#include <stdlib.h> //#include <sal/alloca.h> -#include <stack> -#include <vector> -#include <hash_map> #include <boost/scoped_ptr.hpp> -#include <boost/shared_ptr.hpp> #include <osl/diagnose.h> -#include <rtl/ref.hxx> -#include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/lang/DisposedException.hpp> -#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp> -#include <com/sun/star/xml/sax/XFastParser.hpp> #include <com/sun/star/xml/sax/XFastContextHandler.hpp> #include <com/sun/star/xml/sax/SAXParseException.hpp> #include <com/sun/star/xml/sax/FastToken.hpp> -#include <cppuhelper/factory.hxx> -#include <cppuhelper/weak.hxx> -#include <cppuhelper/implbase2.hxx> +#include "fastparser.hxx" -#include "fastattribs.hxx" -#include "xml2utf.hxx" - -#ifdef SYSTEM_EXPAT -#include <expat.h> -#else -#include "expat/xmlparse.h" -#endif #include <string.h> using ::rtl::OUString; @@ -69,7 +51,6 @@ using namespace ::osl; using namespace ::cppu; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; -using namespace ::com::sun::star::registry; using namespace ::com::sun::star::xml::sax; //using namespace ::com::sun::star::util; using namespace ::com::sun::star::io; @@ -78,11 +59,6 @@ namespace sax_fastparser // -------------------------------------------------------------------- -struct SaxContextImpl; -typedef boost::shared_ptr< SaxContextImpl > SaxContextImplPtr; - -// -------------------------------------------------------------------- - struct SaxContextImpl { Reference< XFastContextHandler > mxContext; @@ -97,16 +73,6 @@ struct SaxContextImpl // -------------------------------------------------------------------- -// Entity binds all information neede for a single file -struct Entity -{ - InputSource maStructSource; - XML_Parser mpParser; - sax_expatwrap::XMLFile2UTFConverter maConverter; -}; - -// -------------------------------------------------------------------- - struct NamespaceDefine { OString maPrefix; @@ -116,10 +82,6 @@ struct NamespaceDefine NamespaceDefine( const OString& rPrefix, sal_Int32 nToken, const OUString& rNamespaceURL ) : maPrefix( rPrefix ), mnToken( nToken ), maNamespaceURL( rNamespaceURL ) {} }; -typedef ::std::hash_map< ::rtl::OUString, sal_Int32, - ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > - > NamespaceMap; - // -------------------------------------------------------------------- // FastLocatorImpl // -------------------------------------------------------------------- @@ -148,107 +110,6 @@ private: // FastSaxParser // -------------------------------------------------------------------- -#define IMPLEMENTATION_NAME "com.sun.star.comp.extensions.xml.sax.FastParser" -#define SERVICE_NAME "com.sun.star.xml.sax.FastParser" - - -// This class implements the external Parser interface -class FastSaxParser : public WeakImplHelper2< XFastParser, XServiceInfo > -{ -public: - FastSaxParser(); - ~FastSaxParser(); - - // The implementation details - static Sequence< OUString > getSupportedServiceNames_Static(void); - - // XFastParser - virtual void SAL_CALL parseStream( const InputSource& aInputSource ) throw (SAXException, IOException, RuntimeException); - virtual void SAL_CALL setFastDocumentHandler( const Reference< XFastDocumentHandler >& Handler ) throw (RuntimeException); - virtual void SAL_CALL setTokenHandler( const Reference< XFastTokenHandler >& Handler ) throw (RuntimeException); - virtual void SAL_CALL registerNamespace( const OUString& NamespaceURL, sal_Int32 NamespaceToken ) throw (IllegalArgumentException, RuntimeException); - virtual void SAL_CALL setErrorHandler( const Reference< XErrorHandler >& Handler ) throw (RuntimeException); - virtual void SAL_CALL setEntityResolver( const Reference< XEntityResolver >& Resolver ) throw (RuntimeException); - virtual void SAL_CALL setLocale( const Locale& Locale ) throw (RuntimeException); - - // XServiceInfo - virtual OUString SAL_CALL getImplementationName( ) throw (RuntimeException); - virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException); - virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); - -public: - // the C-Callbacks for the expat parser - void static callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts); - void static callbackEndElement(void *userData, const XML_Char *name); - void static callbackCharacters( void *userData , const XML_Char *s , int nLen ); - int static callbackExternalEntityRef( XML_Parser parser, const XML_Char *openEntityNames, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); - -public: - void pushEntity( const struct Entity &entity ) { vecEntity.push_back( entity ); } - void popEntity() { vecEntity.pop_back( ); } - struct Entity &getEntity() { return vecEntity.back(); } - -private: - void parse(); - - sal_Int32 GetToken( const OString& rToken ); - sal_Int32 GetToken( const sal_Char* pToken, sal_Int32 nTokenLen = 0 ); - sal_Int32 GetTokenWithPrefix( const OString& rPrefix, const OString& rName ) throw (SAXException); - sal_Int32 GetTokenWithPrefix( const sal_Char*pPrefix, int nPrefixLen, const sal_Char* pName, int nNameLen ) throw (SAXException); - OUString GetNamespaceURL( const OString& rPrefix ) throw (SAXException); - OUString GetNamespaceURL( const sal_Char*pPrefix, int nPrefixLen ) throw (SAXException); - sal_Int32 GetNamespaceToken( const OUString& rNamespaceURL ); - sal_Int32 GetTokenWithNamespaceURL( const OUString& rNamespaceURL, const sal_Char* pName, int nNameLen ); - void DefineNamespace( const OString& rPrefix, const sal_Char* pNamespaceURL ); - sal_Int32 CreateCustomToken( const sal_Char* pToken, int len = 0 ); - - void pushContext(); - void popContext(); - - void splitName( const XML_Char *pwName, const XML_Char *&rpPrefix, sal_Int32 &rPrefixLen, const XML_Char *&rpName, sal_Int32 &rNameLen ); - -private: - Mutex maMutex; - - Reference< XFastDocumentHandler > mxDocumentHandler; - Reference< XFastTokenHandler > mxTokenHandler; - Reference< XErrorHandler > mxErrorHandler; - Reference< XEntityResolver > mxEntityResolver; - rtl::Reference < FastLocatorImpl > mxDocumentLocator; - - rtl::Reference < FastAttributeList > mxAttributes; - - // External entity stack - vector<struct Entity> vecEntity; - - // Exception cannot be thrown through the C-XmlParser (possible resource leaks), - // therefor the maSavedException must be saved somewhere. - Any maSavedException; - sal_Bool mbExceptionWasThrown; - - Locale maLocale; - - std::stack< SaxContextImplPtr > maContextStack; - std::vector< boost::shared_ptr< NamespaceDefine > > maNamespaceDefines; - NamespaceMap maNamespaceMap; -}; - -//-------------------------------------- -// the extern interface -//--------------------------------------- -Reference< XInterface > SAL_CALL FastSaxParser_CreateInstance( const Reference< XMultiServiceFactory > & ) throw(Exception) -{ - FastSaxParser *p = new FastSaxParser; - return Reference< XInterface > ( (OWeakObject * ) p ); -} - -Sequence< OUString > FastSaxParser::getSupportedServiceNames_Static(void) -{ - Sequence<OUString> aRet(1); - aRet.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICE_NAME) ); - return aRet; -} - //--------------------------------------------- // the implementation part //--------------------------------------------- @@ -670,10 +531,17 @@ void FastSaxParser::setLocale( const Locale & Locale ) throw (RuntimeException) maLocale = Locale; } +Sequence< OUString > FastSaxParser::getSupportedServiceNames_Static(void) +{ + Sequence<OUString> aRet(1); + aRet.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(PARSER_SERVICE_NAME) ); + return aRet; +} + // XServiceInfo OUString FastSaxParser::getImplementationName() throw (RuntimeException) { - return OUString::createFromAscii( IMPLEMENTATION_NAME ); + return OUString::createFromAscii( PARSER_IMPLEMENTATION_NAME ); } // XServiceInfo @@ -694,7 +562,7 @@ Sequence< OUString > FastSaxParser::getSupportedServiceNames(void) throw (Runtim { Sequence<OUString> seq(1); - seq.getArray()[0] = OUString::createFromAscii( SERVICE_NAME ); + seq.getArray()[0] = OUString::createFromAscii( PARSER_SERVICE_NAME ); return seq; } @@ -1136,69 +1004,3 @@ int FastSaxParser::callbackExternalEntityRef( XML_Parser parser, } } - -using namespace sax_fastparser; - -extern "C" -{ - -void SAL_CALL component_getImplementationEnvironment( - const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) -{ - *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; -} - - -sal_Bool SAL_CALL component_writeInfo( - void * /*pServiceManager*/, void * pRegistryKey ) -{ - if (pRegistryKey) - { - try - { - Reference< XRegistryKey > xKey( reinterpret_cast< XRegistryKey * >( pRegistryKey ) ); - - Reference< XRegistryKey > xNewKey( xKey->createKey( - OUString::createFromAscii( "/" IMPLEMENTATION_NAME "/UNO/SERVICES" ) ) ); - xNewKey->createKey( OUString::createFromAscii( SERVICE_NAME ) ); - - return sal_True; - } - catch (InvalidRegistryException &) - { - OSL_ENSURE( sal_False, "### InvalidRegistryException!" ); - } - } - return sal_False; -} - -void * SAL_CALL component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * /*pRegistryKey*/ ) -{ - void * pRet = 0; - - if (pServiceManager ) - { - Reference< XSingleServiceFactory > xRet; - Reference< XMultiServiceFactory > xSMgr( reinterpret_cast< XMultiServiceFactory * > ( pServiceManager ) ); - - OUString aImplementationName( OUString::createFromAscii( pImplName ) ); - - if (aImplementationName == OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) ) ) - { - xRet = createSingleFactory( xSMgr, aImplementationName, - FastSaxParser_CreateInstance, - FastSaxParser::getSupportedServiceNames_Static() ); - } - - if (xRet.is()) - { - xRet->acquire(); - pRet = xRet.get(); - } - } - - return pRet; -} - - -} diff --git a/sax/source/fastparser/fastparser.hxx b/sax/source/fastparser/fastparser.hxx new file mode 100644 index 000000000000..07cb6afac77d --- /dev/null +++ b/sax/source/fastparser/fastparser.hxx @@ -0,0 +1,163 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SAX_FASTPARSER_HXX_ +#define _SAX_FASTPARSER_HXX_ + +#include <vector> +#include <stack> +#include <hash_map> +#include <boost/shared_ptr.hpp> +#include <rtl/ref.hxx> +#include <com/sun/star/xml/sax/XFastParser.hpp> +#include <com/sun/star/xml/sax/XFastTokenHandler.hpp> +#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase2.hxx> + +#ifdef SYSTEM_EXPAT +#include <expat.h> +#else +#include "expat/xmlparse.h" +#endif +#include "xml2utf.hxx" + +#include <sax/fastattribs.hxx> + +#define PARSER_IMPLEMENTATION_NAME "com.sun.star.comp.extensions.xml.sax.FastParser" +#define PARSER_SERVICE_NAME "com.sun.star.xml.sax.FastParser" + +namespace sax_fastparser +{ + + class FastLocatorImpl; + struct NamespaceDefine; + struct SaxContextImpl; + typedef boost::shared_ptr< SaxContextImpl > SaxContextImplPtr; + typedef ::std::hash_map< ::rtl::OUString, sal_Int32, + ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > + > NamespaceMap; + +// -------------------------------------------------------------------- + +// Entity binds all information neede for a single file +struct Entity +{ + ::com::sun::star::xml::sax::InputSource maStructSource; + XML_Parser mpParser; + sax_expatwrap::XMLFile2UTFConverter maConverter; +}; + +// -------------------------------------------------------------------- + +// This class implements the external Parser interface +class FastSaxParser : public ::cppu::WeakImplHelper2< ::com::sun::star::xml::sax::XFastParser, ::com::sun::star::lang::XServiceInfo > +{ +public: + FastSaxParser(); + ~FastSaxParser(); + + // The implementation details + static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(void); + + // XFastParser + 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); + virtual void SAL_CALL setFastDocumentHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastDocumentHandler >& Handler ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& Handler ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL registerNamespace( const ::rtl::OUString& NamespaceURL, sal_Int32 NamespaceToken ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setErrorHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XErrorHandler >& Handler ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setEntityResolver( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XEntityResolver >& Resolver ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setLocale( const ::com::sun::star::lang::Locale& rLocale ) throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException); + +public: + // the C-Callbacks for the expat parser + void static callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts); + void static callbackEndElement(void *userData, const XML_Char *name); + void static callbackCharacters( void *userData , const XML_Char *s , int nLen ); + int static callbackExternalEntityRef( XML_Parser parser, const XML_Char *openEntityNames, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); + +public: + void pushEntity( const struct Entity &entity ) { vecEntity.push_back( entity ); } + void popEntity() { vecEntity.pop_back( ); } + struct Entity &getEntity() { return vecEntity.back(); } + +private: + void parse(); + + sal_Int32 GetToken( const ::rtl::OString& rToken ); + sal_Int32 GetToken( const sal_Char* pToken, sal_Int32 nTokenLen = 0 ); + sal_Int32 GetTokenWithPrefix( const ::rtl::OString& rPrefix, const ::rtl::OString& rName ) throw (::com::sun::star::xml::sax::SAXException); + sal_Int32 GetTokenWithPrefix( const sal_Char*pPrefix, int nPrefixLen, const sal_Char* pName, int nNameLen ) throw (::com::sun::star::xml::sax::SAXException); + ::rtl::OUString GetNamespaceURL( const ::rtl::OString& rPrefix ) throw (::com::sun::star::xml::sax::SAXException); + ::rtl::OUString GetNamespaceURL( const sal_Char*pPrefix, int nPrefixLen ) throw (::com::sun::star::xml::sax::SAXException); + sal_Int32 GetNamespaceToken( const ::rtl::OUString& rNamespaceURL ); + sal_Int32 GetTokenWithNamespaceURL( const ::rtl::OUString& rNamespaceURL, const sal_Char* pName, int nNameLen ); + void DefineNamespace( const ::rtl::OString& rPrefix, const sal_Char* pNamespaceURL ); + sal_Int32 CreateCustomToken( const sal_Char* pToken, int len = 0 ); + + void pushContext(); + void popContext(); + + void splitName( const XML_Char *pwName, const XML_Char *&rpPrefix, sal_Int32 &rPrefixLen, const XML_Char *&rpName, sal_Int32 &rNameLen ); + +private: + ::osl::Mutex maMutex; + + ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastDocumentHandler > mxDocumentHandler; + ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxTokenHandler; + ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XErrorHandler > mxErrorHandler; + ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XEntityResolver > mxEntityResolver; + + rtl::Reference < FastLocatorImpl > mxDocumentLocator; + rtl::Reference < FastAttributeList > mxAttributes; + + // External entity stack + std::vector< struct Entity > vecEntity; + + // Exception cannot be thrown through the C-XmlParser (possible resource leaks), + // therefor the maSavedException must be saved somewhere. + ::com::sun::star::uno::Any maSavedException; + sal_Bool mbExceptionWasThrown; + + ::com::sun::star::lang::Locale maLocale; + + std::stack< SaxContextImplPtr > maContextStack; + std::vector< boost::shared_ptr< NamespaceDefine > > maNamespaceDefines; + NamespaceMap maNamespaceMap; +}; + +} + +#endif // _SAX_FASTPARSER_HXX_ diff --git a/sax/source/fastparser/makefile.mk b/sax/source/fastparser/makefile.mk index d3a6a9312978..625d7790ed1a 100644 --- a/sax/source/fastparser/makefile.mk +++ b/sax/source/fastparser/makefile.mk @@ -37,7 +37,7 @@ ENABLE_EXCEPTIONS=TRUE # --- Settings ----------------------------------------------------- .INCLUDE : settings.mk -DLLPRE = +DLLPRE = .IF "$(SYSTEM_ZLIB)" == "YES" CFLAGS+=-DSYSTEM_ZLIB @@ -50,8 +50,8 @@ CFLAGS+=-DSYSTEM_EXPAT #----------------------------------------------------------- SLOFILES =\ + $(SLO)$/facreg.obj\ $(SLO)$/fastparser.obj\ - $(SLO)$/fastattribs.obj\ $(SLO)$/xml2utf.obj SHL1TARGET= $(TARGET) @@ -59,8 +59,10 @@ SHL1IMPLIB= i$(TARGET) SHL1STDLIBS= \ $(SALLIB) \ + $(SAXLIB) \ $(CPPULIB) \ $(CPPUHELPERLIB)\ + $(COMPHELPERLIB)\ $(EXPATASCII3RDLIB) SHL1DEPN= diff --git a/sax/source/fastparser/fastattribs.cxx b/sax/source/tools/fastattribs.cxx index a414071bdb49..43e5f75d2907 100644 --- a/sax/source/fastparser/fastattribs.cxx +++ b/sax/source/tools/fastattribs.cxx @@ -31,7 +31,7 @@ #include <algorithm> #include <boost/bind.hpp> -#include "fastattribs.hxx" +#include <sax/fastattribs.hxx> using ::rtl::OUString; using ::rtl::OString; @@ -41,40 +41,25 @@ using namespace ::com::sun::star::xml::sax; namespace sax_fastparser { -struct UnknownAttribute +UnknownAttribute::UnknownAttribute( const OUString& rNamespaceURL, const OString& rName, const OString& rValue ) + : maNamespaceURL( rNamespaceURL ), maName( rName ), maValue( rValue ) { - OUString maNamespaceURL; - OString maName; - OString maValue; - - UnknownAttribute( const OUString& rNamespaceURL, const OString& rName, const OString& rValue ) - : maNamespaceURL( rNamespaceURL ), maName( rName ), maValue( rValue ) {} - - UnknownAttribute( const OString& rName, const OString& rValue ) - : maName( rName ), maValue( rValue ) {} +} -/* - UnknownAttribute( const UnknownAttribute& r ) - : maNamespaceURL( r.maNamespaceURL ), maName( r.maName ), maValue( r.maValue ) {} +UnknownAttribute::UnknownAttribute( const OString& rName, const OString& rValue ) + : maName( rName ), maValue( rValue ) +{ +} - const UnknownAttribute& operator=( const UnknownAttribute& r ) - { - maNamespaceURL = r.maNamespaceURL; - maName = r.maName; - maValue = r.maValue; - return *this; - } -*/ - void FillAttribute( Attribute* pAttrib ) const +void UnknownAttribute::FillAttribute( Attribute* pAttrib ) const +{ + if( pAttrib ) { - if( pAttrib ) - { - pAttrib->Name = OStringToOUString( maName, RTL_TEXTENCODING_UTF8 ); - pAttrib->NamespaceURL = maNamespaceURL; - pAttrib->Value = OStringToOUString( maValue, RTL_TEXTENCODING_UTF8 ); - } + pAttrib->Name = OStringToOUString( maName, RTL_TEXTENCODING_UTF8 ); + pAttrib->NamespaceURL = maNamespaceURL; + pAttrib->Value = OStringToOUString( maValue, RTL_TEXTENCODING_UTF8 ); } -}; +} FastAttributeList::FastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xTokenHandler ) : mxTokenHandler( xTokenHandler ) @@ -165,7 +150,21 @@ Sequence< Attribute > FastAttributeList::getUnknownAttributes( ) throw (Runtime { Sequence< Attribute > aSeq( maUnknownAttributes.size() ); Attribute* pAttr = aSeq.getArray(); - std::for_each( maUnknownAttributes.begin(), maUnknownAttributes.end(), bind(&UnknownAttribute::FillAttribute, _1, pAttr++ ) ); + for( UnknownAttributeList::iterator attrIter = maUnknownAttributes.begin(); attrIter != maUnknownAttributes.end(); attrIter++ ) + (*attrIter).FillAttribute( pAttr++ ); + return aSeq; +} +Sequence< FastAttribute > FastAttributeList::getFastAttributes( ) throw (RuntimeException) +{ + Sequence< FastAttribute > aSeq( maAttributes.size() ); + FastAttribute* pAttr = aSeq.getArray(); + FastAttributeMap::iterator fastAttrIter = maAttributes.begin(); + for(; fastAttrIter != maAttributes.end(); fastAttrIter++ ) + { + pAttr->Token = fastAttrIter->first; + pAttr->Value = OStringToOUString( fastAttrIter->second, RTL_TEXTENCODING_UTF8 ); + pAttr++; + } return aSeq; } diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx new file mode 100644 index 000000000000..4603ceed3343 --- /dev/null +++ b/sax/source/tools/fastserializer.cxx @@ -0,0 +1,388 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: contexthandler2.cxx,v $ + * + * $Revision: 1.1.2.2 $ + * + * last change: $Author: dr $ $Date: 2008/02/11 10:43:07 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "fastserializer.hxx" +#include <rtl/ustrbuf.hxx> + +#include <com/sun/star/xml/Attribute.hpp> +#include <com/sun/star/xml/FastAttribute.hpp> +#include <com/sun/star/xml/sax/XFastAttributeList.hpp> + +#include <string.h> + +using ::rtl::OString; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; +using ::rtl::OUStringToOString; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::xml::FastAttribute; +using ::com::sun::star::xml::Attribute; +using ::com::sun::star::xml::sax::SAXException; +using ::com::sun::star::xml::sax::XFastAttributeList; +using ::com::sun::star::xml::sax::XFastTokenHandler; +using ::com::sun::star::xml::sax::XFastSerializer; +using ::com::sun::star::io::XOutputStream; +using ::com::sun::star::io::NotConnectedException; +using ::com::sun::star::io::IOException; +using ::com::sun::star::io::BufferSizeExceededException; + +static Sequence< sal_Int8 > aClosingBracket((sal_Int8 *)">", 1); +static Sequence< sal_Int8 > aSlashAndClosingBracket((sal_Int8 *)"/>", 2); +static Sequence< sal_Int8 > aColon((sal_Int8 *)":", 1); +static Sequence< sal_Int8 > aOpeningBracket((sal_Int8 *)"<", 1); +static Sequence< sal_Int8 > aOpeningBracketAndSlash((sal_Int8 *)"</", 2); +static Sequence< sal_Int8 > aQuote((sal_Int8 *)"\"", 1); +static Sequence< sal_Int8 > aEqualSignAndQuote((sal_Int8 *)"=\"", 2); +static Sequence< sal_Int8 > aSpace((sal_Int8 *)" ", 1); +static Sequence< sal_Int8 > aXmlHeader((sal_Int8*) "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n", 56); + +#define HAS_NAMESPACE(x) ((x & 0xffff0000) != 0) +#define NAMESPACE(x) (x >> 16) +#define TOKEN(x) (x & 0xffff) + +namespace sax_fastparser { + FastSaxSerializer::FastSaxSerializer( ) : mxOutputStream(), mxFastTokenHandler(), maMarkStack() {} + FastSaxSerializer::~FastSaxSerializer() {} + + void SAL_CALL FastSaxSerializer::startDocument( ) throw (SAXException, RuntimeException) + { + if (!mxOutputStream.is()) + return; + writeBytes(aXmlHeader); + } + + OUString FastSaxSerializer::escapeXml( const OUString& s ) + { + ::rtl::OUStringBuffer sBuf( s.getLength() ); + const sal_Unicode* pStr = s; + sal_Int32 nLen = s.getLength(); + for( sal_Int32 i = 0; i < nLen; ++i) + { + sal_Unicode c = pStr[ i ]; + switch( c ) + { + case '<': sBuf.appendAscii( "<" ); break; + case '>': sBuf.appendAscii( ">" ); break; + case '&': sBuf.appendAscii( "&" ); break; + case '\'': sBuf.appendAscii( "'" ); break; + case '"': sBuf.appendAscii( """ ); break; + default: sBuf.append( c ); break; + } + } + return sBuf.makeStringAndClear(); + } + + void FastSaxSerializer::write( const OUString& s ) + { + OString sOutput( OUStringToOString( s, RTL_TEXTENCODING_UTF8 ) ); + writeBytes( Sequence< sal_Int8 >( + reinterpret_cast< const sal_Int8*>( sOutput.getStr() ), + sOutput.getLength() ) ); + } + + void SAL_CALL FastSaxSerializer::endDocument( ) throw (SAXException, RuntimeException) + { + if (!mxOutputStream.is()) + return; + } + + void SAL_CALL FastSaxSerializer::writeId( ::sal_Int32 nElement ) + { + if( HAS_NAMESPACE( nElement ) ) { + writeBytes(mxFastTokenHandler->getUTF8Identifier(NAMESPACE(nElement))); + writeBytes(aColon); + writeBytes(mxFastTokenHandler->getUTF8Identifier(TOKEN(nElement))); + } else + writeBytes(mxFastTokenHandler->getUTF8Identifier(nElement)); + } + + void SAL_CALL FastSaxSerializer::startFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs ) + throw (SAXException, RuntimeException) + { + if (!mxOutputStream.is()) + return; + + writeBytes(aOpeningBracket); + + writeId(Element); + writeFastAttributeList(Attribs); + + writeBytes(aClosingBracket); + } + + void SAL_CALL FastSaxSerializer::startUnknownElement( const OUString& Namespace, const OUString& Name, const Reference< XFastAttributeList >& Attribs ) + throw (SAXException, RuntimeException) + { + if (!mxOutputStream.is()) + return; + + writeBytes(aOpeningBracket); + + if (Namespace.getLength()) + { + write(Namespace); + writeBytes(aColon); + } + + write(Name); + + writeFastAttributeList(Attribs); + + writeBytes(aClosingBracket); + } + + void SAL_CALL FastSaxSerializer::endFastElement( ::sal_Int32 Element ) + throw (SAXException, RuntimeException) + { + if (!mxOutputStream.is()) + return; + + writeBytes(aOpeningBracketAndSlash); + + writeId(Element); + + writeBytes(aClosingBracket); + } + + void SAL_CALL FastSaxSerializer::endUnknownElement( const OUString& Namespace, const OUString& Name ) + throw (SAXException, RuntimeException) + { + if (!mxOutputStream.is()) + return; + + writeBytes(aOpeningBracketAndSlash); + + if (Namespace.getLength()) + { + write(Namespace); + writeBytes(aColon); + } + + write(Name); + + writeBytes(aClosingBracket); + } + + void SAL_CALL FastSaxSerializer::singleFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs ) + throw (SAXException, RuntimeException) + { + if (!mxOutputStream.is()) + return; + + writeBytes(aOpeningBracket); + + writeId(Element); + writeFastAttributeList(Attribs); + + writeBytes(aSlashAndClosingBracket); + } + + void SAL_CALL FastSaxSerializer::singleUnknownElement( const OUString& Namespace, const OUString& Name, const Reference< XFastAttributeList >& Attribs ) + throw (SAXException, RuntimeException) + { + if (!mxOutputStream.is()) + return; + + writeBytes(aOpeningBracket); + + if (Namespace.getLength()) + { + write(Namespace); + writeBytes(aColon); + } + + write(Name); + + writeFastAttributeList(Attribs); + + writeBytes(aSlashAndClosingBracket); + } + + void SAL_CALL FastSaxSerializer::characters( const OUString& aChars ) + throw (SAXException, RuntimeException) + { + if (!mxOutputStream.is()) + return; + + write( aChars ); + } + + void SAL_CALL FastSaxSerializer::setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream ) + throw (::com::sun::star::uno::RuntimeException) + { + mxOutputStream = xOutputStream; + } + + void SAL_CALL FastSaxSerializer::setFastTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xFastTokenHandler ) + throw (::com::sun::star::uno::RuntimeException) + { + mxFastTokenHandler = xFastTokenHandler; + } + void FastSaxSerializer::writeFastAttributeList( const Reference< XFastAttributeList >& Attribs ) + { + Sequence< Attribute > aAttrSeq = Attribs->getUnknownAttributes(); + const Attribute *pAttr = aAttrSeq.getConstArray(); + sal_Int32 nAttrLength = aAttrSeq.getLength(); + for (sal_Int32 i = 0; i < nAttrLength; i++) + { + writeBytes(aSpace); + + write(pAttr[i].Name); + writeBytes(aEqualSignAndQuote); + write(escapeXml(pAttr[i].Value)); + writeBytes(aQuote); + } + + Sequence< FastAttribute > aFastAttrSeq = Attribs->getFastAttributes(); + const FastAttribute *pFastAttr = aFastAttrSeq.getConstArray(); + sal_Int32 nFastAttrLength = aFastAttrSeq.getLength(); + for (sal_Int32 j = 0; j < nFastAttrLength; j++) + { + writeBytes(aSpace); + + sal_Int32 nToken = pFastAttr[j].Token; + writeId(nToken); + + writeBytes(aEqualSignAndQuote); + + write(escapeXml(Attribs->getValue(pFastAttr[j].Token))); + + writeBytes(aQuote); + } + } + + // XServiceInfo + OUString FastSaxSerializer::getImplementationName() throw (RuntimeException) + { + return OUString::createFromAscii( SERIALIZER_IMPLEMENTATION_NAME ); + } + + // XServiceInfo + sal_Bool FastSaxSerializer::supportsService(const OUString& ServiceName) throw (RuntimeException) + { + Sequence< OUString > aSNL = getSupportedServiceNames(); + const OUString * pArray = aSNL.getConstArray(); + + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + + return sal_False; + } + + // XServiceInfo + Sequence< OUString > FastSaxSerializer::getSupportedServiceNames(void) throw (RuntimeException) + { + Sequence<OUString> seq(1); + seq.getArray()[0] = OUString::createFromAscii( SERIALIZER_SERVICE_NAME ); + return seq; + } + + OUString FastSaxSerializer::getImplementationName_Static() + { + return OUString::createFromAscii( SERIALIZER_IMPLEMENTATION_NAME ); + } + + Sequence< OUString > FastSaxSerializer::getSupportedServiceNames_Static(void) + { + Sequence<OUString> aRet(1); + aRet.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(SERIALIZER_SERVICE_NAME) ); + return aRet; + } + + void FastSaxSerializer::mark() + { + maMarkStack.push( Int8Sequence() ); + } + + void FastSaxSerializer::mergeTopMarks( bool bPrepend ) + { + if ( maMarkStack.empty() ) + return; + + if ( maMarkStack.size() == 1 ) + { + mxOutputStream->writeBytes( maMarkStack.top() ); + maMarkStack.pop(); + } + else + { + const Int8Sequence aMerge( maMarkStack.top() ); + maMarkStack.pop(); + + sal_Int32 nMergeLen = aMerge.getLength(); + if ( nMergeLen > 0 ) + { + Int8Sequence &rTop = maMarkStack.top(); + sal_Int32 nTopLen = rTop.getLength(); + + rTop.realloc( nTopLen + nMergeLen ); + if ( bPrepend ) + { + // prepend the aMerge to the rTop + memmove( rTop.getArray() + nMergeLen, rTop.getConstArray(), nTopLen ); + memcpy( rTop.getArray(), aMerge.getConstArray(), nMergeLen ); + } + else + { + // append the aMerge to the rTop + memcpy( rTop.getArray() + nTopLen, aMerge.getConstArray(), nMergeLen ); + } + } + } + } + + void FastSaxSerializer::writeBytes( const Sequence< ::sal_Int8 >& aData ) throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException ) + { + if ( maMarkStack.empty() ) + mxOutputStream->writeBytes( aData ); + else + { + sal_Int32 nDataLen = aData.getLength(); + if ( nDataLen > 0 ) + { + Int8Sequence &rTop = maMarkStack.top(); + sal_Int32 nTopLen = rTop.getLength(); + + rTop.realloc( nTopLen + nDataLen ); + memcpy( rTop.getArray() + nTopLen, aData.getConstArray(), nDataLen ); + } + } + } + +} // namespace sax_fastparser + diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx new file mode 100644 index 000000000000..132b495c0a8b --- /dev/null +++ b/sax/source/tools/fastserializer.hxx @@ -0,0 +1,147 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: serializer.hxx,v $ + * + * $Revision: 1.2.4.1 $ + * + * last change: $Author: dr $ $Date: 2008/02/15 12:56:11 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef SAX_FASTSERIALIZER_HXX +#define SAX_FASTSERIALIZER_HXX + +#include <com/sun/star/xml/sax/XFastSerializer.hpp> +#include <com/sun/star/xml/sax/XFastTokenHandler.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <cppuhelper/implbase2.hxx> + +#include <stack> + +#include "sax/dllapi.h" + +#define SERIALIZER_IMPLEMENTATION_NAME "com.sun.star.comp.extensions.xml.sax.FastSerializer" +#define SERIALIZER_SERVICE_NAME "com.sun.star.xml.sax.FastSerializer" + +namespace sax_fastparser { + +class SAX_DLLPUBLIC FastSaxSerializer : public ::cppu::WeakImplHelper2< ::com::sun::star::xml::sax::XFastSerializer, ::com::sun::star::lang::XServiceInfo > +{ +public: + explicit FastSaxSerializer( ); + virtual ~FastSaxSerializer(); + + ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > getOutputStream() {return mxOutputStream;} + + // The implementation details + static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(void); + static ::rtl::OUString getImplementationName_Static(); + + // XFastSerializer + virtual void SAL_CALL startDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endDocument( ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL startFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) + throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) + throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) + throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) + throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL singleFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) + throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL singleUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) + throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) + throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setFastTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xFastTokenHandler ) + throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw ( ::com::sun::star::uno::RuntimeException ); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw ( ::com::sun::star::uno::RuntimeException ); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw ( ::com::sun::star::uno::RuntimeException ); + + // C++ helpers + virtual void SAL_CALL writeId( ::sal_Int32 Element ); + + static ::rtl::OUString escapeXml( const ::rtl::OUString& s ); + +public: + /** From now on, don't write directly to the stream, but to top of a stack. + + This is to be able to change the order of the data being written. + If you need to write eg. + p, r, rPr, [something], /rPr, t, [text], /r, /p, + but get it in order + p, r, t, [text], /t, rPr, [something], /rPr, /r, /p, + simply do + p, r, mark(), t, [text], /t, mark(), rPr, [something], /rPr, + mergeTopMarks( true ), mergeTopMarks(), /r, /p + and you are done. + */ + void mark(); + + /** Merge 2 topmost marks. + + There are 2 possibilities - prepend the top before the second top-most + mark, or append it; prepending brings the possibility to switch parts + of the output. + + Writes the result to the output stream if the mark stack becomes empty + by the operation. + + @see mark() + */ + void mergeTopMarks( bool bPrepend = false ); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > mxOutputStream; + ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxFastTokenHandler; + + typedef ::com::sun::star::uno::Sequence< ::sal_Int8 > Int8Sequence; + ::std::stack< Int8Sequence > maMarkStack; + + void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ); + void write( const ::rtl::OUString& s ); + +protected: + /** Forward the call to the output stream, or write to the stack. + + The latter in the case that we are inside a mark(). + */ + void writeBytes( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); +}; + +} // namespace sax_fastparser + +#endif + diff --git a/sax/source/tools/fshelper.cxx b/sax/source/tools/fshelper.cxx new file mode 100644 index 000000000000..594a60ba1d76 --- /dev/null +++ b/sax/source/tools/fshelper.cxx @@ -0,0 +1,195 @@ +#include <sax/fshelper.hxx> +#include "fastserializer.hxx" +#include <com/sun/star/xml/sax/XFastTokenHandler.hpp> +#include <comphelper/processfactory.hxx> +#include <rtl/ustrbuf.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace sax_fastparser { + +FastSerializerHelper::FastSerializerHelper(const Reference< io::XOutputStream >& xOutputStream ) : + mpSerializer(new FastSaxSerializer()) +{ + Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); + mxTokenHandler = Reference<xml::sax::XFastTokenHandler> ( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.FastTokenHandler") ) ), UNO_QUERY_THROW ); + + mpSerializer->setFastTokenHandler( mxTokenHandler ); + mpSerializer->setOutputStream( xOutputStream ); + mpSerializer->startDocument(); +} + +FastSerializerHelper::~FastSerializerHelper() +{ + mpSerializer->endDocument(); + + if (mpSerializer) { + delete mpSerializer; + mpSerializer = NULL; + } +} + +void FastSerializerHelper::startElement(const char* elementName, ...) +{ + FastAttributeList* pAttrList = new FastAttributeList( mxTokenHandler ); + va_list args; + va_start(args, elementName); + while (true) + { + const char* pName = va_arg(args, const char*); + if (!pName) + break; + const char* pValue = va_arg(args, const char*); + if (pValue) + pAttrList->addUnknown(pName, pValue); + } + va_end(args); + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastAttributeList> xAttrList(pAttrList); + mpSerializer->startUnknownElement(::rtl::OUString(), ::rtl::OUString::createFromAscii(elementName), xAttrList); +} + +void FastSerializerHelper::singleElement(const char* elementName, ...) +{ + FastAttributeList* pAttrList = new FastAttributeList( mxTokenHandler ); + va_list args; + va_start(args, elementName); + while (true) + { + const char* pName = va_arg(args, const char*); + if (!pName) + break; + const char* pValue = va_arg(args, const char*); + if (pValue) + pAttrList->addUnknown(pName, pValue); + } + va_end(args); + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastAttributeList> xAttrList(pAttrList); + mpSerializer->singleUnknownElement(::rtl::OUString(), ::rtl::OUString::createFromAscii(elementName), xAttrList); +} + +void FastSerializerHelper::endElement(const char* elementName) +{ + mpSerializer->endUnknownElement(::rtl::OUString(), ::rtl::OUString::createFromAscii(elementName)); +} + +void FastSerializerHelper::startElementV(sal_Int32 elementTokenId, va_list args) +{ + FastAttributeList* pAttrList = new FastAttributeList( mxTokenHandler ); + + while (true) + { + sal_Int32 nName = va_arg(args, sal_Int32); + if (nName == FSEND) + break; + const char* pValue = va_arg(args, const char*); + if (pValue) + pAttrList->add(nName, pValue); + } + + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastAttributeList> xAttrList(pAttrList); + mpSerializer->startFastElement(elementTokenId, xAttrList); +} + +void FastSerializerHelper::singleElementV(sal_Int32 elementTokenId, va_list args) +{ + FastAttributeList* pAttrList = new FastAttributeList( mxTokenHandler ); + + while (true) + { + sal_Int32 nName = va_arg(args, sal_Int32); + if (nName == FSEND) + break; + const char* pValue = va_arg(args, const char*); + if (pValue) + pAttrList->add(nName, pValue); + } + + const com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastAttributeList> xAttrList(pAttrList); + mpSerializer->singleFastElement(elementTokenId, xAttrList); +} + +void FastSerializerHelper::endElement(sal_Int32 elementTokenId) +{ + mpSerializer->endFastElement(elementTokenId); +} + +void FastSerializerHelper::singleElement(const char* elementName, XFastAttributeListRef xAttrList) +{ + mpSerializer->singleUnknownElement(::rtl::OUString(), ::rtl::OUString::createFromAscii(elementName), xAttrList); +} + +void FastSerializerHelper::singleElementV(sal_Int32 elementTokenId, XFastAttributeListRef xAttrList) +{ + mpSerializer->singleFastElement(elementTokenId, xAttrList); +} + +FastSerializerHelper* FastSerializerHelper::write(const char* value) +{ + return write(rtl::OUString::createFromAscii(value)); +} + +FastSerializerHelper* FastSerializerHelper::write(const rtl::OUString& value) +{ + mpSerializer->characters(value); + return this; +} + +FastSerializerHelper* FastSerializerHelper::write(sal_Int32 value) +{ + return write(::rtl::OUString::valueOf(value)); +} + +FastSerializerHelper* FastSerializerHelper::write(sal_Int64 value) +{ + return write(::rtl::OUString::valueOf(value)); +} + +FastSerializerHelper* FastSerializerHelper::write(float value) +{ + return write(::rtl::OUString::valueOf(value)); +} + +FastSerializerHelper* FastSerializerHelper::write(double value) +{ + return write(::rtl::OUString::valueOf(value)); +} + +FastSerializerHelper* FastSerializerHelper::writeEscaped(const char* value) +{ + return writeEscaped(::rtl::OUString::createFromAscii(value)); +} + +FastSerializerHelper* FastSerializerHelper::writeEscaped(const ::rtl::OUString& value) +{ + return write(FastSaxSerializer::escapeXml(value)); +} + +FastSerializerHelper* FastSerializerHelper::writeId(sal_Int32 tokenId) +{ + mpSerializer->writeId(tokenId); + return this; +} + +::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > FastSerializerHelper::getOutputStream() +{ + return mpSerializer->getOutputStream(); +} + +void FastSerializerHelper::mark() +{ + mpSerializer->mark(); +} + +void FastSerializerHelper::mergeTopMarks( bool bPrepend ) +{ + mpSerializer->mergeTopMarks( bPrepend ); +} + +FastAttributeList * FastSerializerHelper::createAttrList() +{ + return new FastAttributeList( mxTokenHandler ); +} + + +} diff --git a/sax/source/tools/makefile.mk b/sax/source/tools/makefile.mk index 2812218fd440..1f806aef74b4 100644 --- a/sax/source/tools/makefile.mk +++ b/sax/source/tools/makefile.mk @@ -32,7 +32,7 @@ PRJ=..$/.. PRJNAME=sax -TARGET=saxtools +TARGET=sax ENABLE_EXCEPTIONS=TRUE # --- Settings ----------------------------------------------------- @@ -43,7 +43,30 @@ ENABLE_EXCEPTIONS=TRUE # --- Files -------------------------------------------------------- SLOFILES = \ - $(SLO)$/converter.obj + $(SLO)$/converter.obj \ + $(SLO)$/fastattribs.obj \ + $(SLO)$/fastserializer.obj \ + $(SLO)$/fshelper.obj + +SHL1TARGET= $(TARGET)$(DLLPOSTFIX) +SHL1IMPLIB= i$(TARGET) + +SHL1STDLIBS= \ + $(VOSLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB)\ + $(COMPHELPERLIB)\ + $(RTLLIB) \ + $(SALLIB) \ + $(ONELIB) \ + $(SALHELPERLIB) + +SHL1DEPN= +SHL1OBJS= $(SLOFILES) +SHL1USE_EXPORTS=name +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +DEF1NAME= $(SHL1TARGET) +DEFLIB1NAME= $(TARGET) # --- Targets ------------------------------------------------------- |