diff options
Diffstat (limited to 'sax/source/tools')
-rw-r--r-- | sax/source/tools/fastattribs.cxx | 171 | ||||
-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 |
5 files changed, 926 insertions, 2 deletions
diff --git a/sax/source/tools/fastattribs.cxx b/sax/source/tools/fastattribs.cxx new file mode 100644 index 000000000000..43e5f75d2907 --- /dev/null +++ b/sax/source/tools/fastattribs.cxx @@ -0,0 +1,171 @@ +/************************************************************************* + * + * 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: fastattribs.cxx,v $ + * $Revision: 1.3 $ + * + * 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. + * + ************************************************************************/ + +#include <algorithm> +#include <boost/bind.hpp> + +#include <sax/fastattribs.hxx> + +using ::rtl::OUString; +using ::rtl::OString; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml; +using namespace ::com::sun::star::xml::sax; +namespace sax_fastparser +{ + +UnknownAttribute::UnknownAttribute( const OUString& rNamespaceURL, const OString& rName, const OString& rValue ) + : maNamespaceURL( rNamespaceURL ), maName( rName ), maValue( rValue ) +{ +} + +UnknownAttribute::UnknownAttribute( const OString& rName, const OString& rValue ) + : maName( rName ), maValue( rValue ) +{ +} + +void UnknownAttribute::FillAttribute( Attribute* pAttrib ) const +{ + if( pAttrib ) + { + 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 ) +{ + maLastIter = maAttributes.end(); +} + +FastAttributeList::~FastAttributeList() +{ +} + +void FastAttributeList::clear() +{ + maAttributes.clear(); + maUnknownAttributes.clear(); + maLastIter = maAttributes.end(); +} + +void FastAttributeList::add( sal_Int32 nToken, const OString& rValue ) +{ + maAttributes[nToken] = rValue; +} + +void FastAttributeList::addUnknown( const OUString& rNamespaceURL, const OString& rName, const OString& rValue ) +{ + maUnknownAttributes.push_back( UnknownAttribute( rNamespaceURL, rName, rValue ) ); +} + +void FastAttributeList::addUnknown( const OString& rName, const OString& rValue ) +{ + maUnknownAttributes.push_back( UnknownAttribute( rName, rValue ) ); +} + +// XFastAttributeList +sal_Bool FastAttributeList::hasAttribute( ::sal_Int32 Token ) throw (RuntimeException) +{ + maLastIter = maAttributes.find( Token ); + return ( maLastIter != maAttributes.end() ) ? sal_True : sal_False; +} + +sal_Int32 FastAttributeList::getValueToken( ::sal_Int32 Token ) throw (SAXException, RuntimeException) +{ + if( ( maLastIter == maAttributes.end() ) || ( ( *maLastIter ).first != Token ) ) + maLastIter = maAttributes.find( Token ); + + if( maLastIter == maAttributes.end() ) + throw SAXException(); + + Sequence< sal_Int8 > aSeq( (sal_Int8*)(*maLastIter).second.getStr(), (*maLastIter).second.getLength() ) ; + return mxTokenHandler->getTokenFromUTF8( aSeq ); +} + +sal_Int32 FastAttributeList::getOptionalValueToken( ::sal_Int32 Token, ::sal_Int32 Default ) throw (RuntimeException) +{ + if( ( maLastIter == maAttributes.end() ) || ( ( *maLastIter ).first != Token ) ) + maLastIter = maAttributes.find( Token ); + + if( maLastIter == maAttributes.end() ) + return Default; + + Sequence< sal_Int8 > aSeq( (sal_Int8*)(*maLastIter).second.getStr(), (*maLastIter).second.getLength() ) ; + return mxTokenHandler->getTokenFromUTF8( aSeq ); +} + +OUString FastAttributeList::getValue( ::sal_Int32 Token ) throw (SAXException, RuntimeException) +{ + if( ( maLastIter == maAttributes.end() ) || ( ( *maLastIter ).first != Token ) ) + maLastIter = maAttributes.find( Token ); + + if( maLastIter == maAttributes.end() ) + throw SAXException(); + + return OStringToOUString( (*maLastIter).second, RTL_TEXTENCODING_UTF8 ); +} + +OUString FastAttributeList::getOptionalValue( ::sal_Int32 Token ) throw (RuntimeException) +{ + if( ( maLastIter == maAttributes.end() ) || ( ( *maLastIter ).first != Token ) ) + maLastIter = maAttributes.find( Token ); + + OUString aRet; + if( maLastIter != maAttributes.end() ) + aRet = OStringToOUString( (*maLastIter).second, RTL_TEXTENCODING_UTF8 ); + + return aRet; +} +Sequence< Attribute > FastAttributeList::getUnknownAttributes( ) throw (RuntimeException) +{ + Sequence< Attribute > aSeq( maUnknownAttributes.size() ); + Attribute* pAttr = aSeq.getArray(); + 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 ------------------------------------------------------- |