[Libreoffice-commits] core.git: 14 commits - include/sax sax/source sc/source sd/source

Matúš Kukan matus.kukan at collabora.com
Thu Oct 23 02:55:11 PDT 2014


 include/sax/fastattribs.hxx              |   42 ++---
 include/sax/fshelper.hxx                 |    6 
 sax/source/fastparser/fastparser.cxx     |    7 
 sax/source/tools/CachedOutputStream.hxx  |  102 ++++++++++++++
 sax/source/tools/fastattribs.cxx         |   41 +----
 sax/source/tools/fastserializer.cxx      |  218 ++++++++++++++-----------------
 sax/source/tools/fastserializer.hxx      |   69 +++------
 sax/source/tools/fshelper.cxx            |   54 ++++---
 sc/source/filter/excel/excdoc.cxx        |    2 
 sc/source/filter/excel/xestream.cxx      |    7 
 sd/source/filter/eppt/pptx-epptooxml.cxx |    2 
 11 files changed, 310 insertions(+), 240 deletions(-)

New commits:
commit d45607c4be485952158c58b1ebb83f7632f1a057
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Mon Sep 29 16:31:24 2014 +0200

    Revert recent changes to comphelper::OSequenceOutputStream
    
    Some of the changes could be wrong and we don't need them.
    
    This reverts commit 784d4bea86d8cbb3a855e557c465ce50a049cefc.
    This reverts commit 8524d5aba59148eef94859289f00ab6477e0e821.
    This reverts commit 018f1deae884febbbe639c7ee46b45ce4807e9d3.
    This reverts commit 8124fddc5803b4e104d4fc2456cb92cb030d9436.
    
    We use our own helper cache class in FastSaxSerializer
    since f736eba5a9df8645849a37b08d2764a5f495ab45.
    
    Change-Id: Iaca6b5b11cb32595db4420a02fa72b0007cf6286

diff --git a/comphelper/source/streaming/seqstream.cxx b/comphelper/source/streaming/seqstream.cxx
index 91fdc7d7..5bc44a5 100644
--- a/comphelper/source/streaming/seqstream.cxx
+++ b/comphelper/source/streaming/seqstream.cxx
@@ -156,19 +156,15 @@ OSequenceOutputStream::OSequenceOutputStream(Sequence< sal_Int8 >& _rSeq, double
         // this heuristic is as good as any other ... supply better parameters if you don't like it :)
 }
 
-void SAL_CALL OSequenceOutputStream::writeBytes( const Sequence< sal_Int8 >& _rData ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception)
-{
-    writeBytes(_rData.getConstArray(), _rData.getLength());
-}
 
-void SAL_CALL OSequenceOutputStream::writeBytes( const sal_Int8* pStr, sal_Int32 nLen )
-    throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception)
+void SAL_CALL OSequenceOutputStream::writeBytes( const Sequence< sal_Int8 >& _rData ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception)
 {
+    MutexGuard aGuard(m_aMutex);
     if (!m_bConnected)
         throw NotConnectedException();
 
     // ensure the sequence has enough space left
-    if (m_nSize + nLen > m_rSequence.getLength())
+    if (m_nSize + _rData.getLength() > m_rSequence.getLength())
     {
         sal_Int32 nCurrentLength = m_rSequence.getLength();
         sal_Int32 nNewLength = static_cast< sal_Int32 >(
@@ -182,18 +178,18 @@ void SAL_CALL OSequenceOutputStream::writeBytes( const sal_Int8* pStr, sal_Int32
             // such a large step is not allowed
             nNewLength = nCurrentLength + m_nMaximumResize;
 
-        if (nNewLength < m_nSize + nLen)
+        if (nNewLength < m_nSize + _rData.getLength())
         {   // it's not enough .... the data would not fit
 
             // let's take the double amount of the length of the data to be written, as the next write
             // request could be as large as this one
-            sal_Int32 nNewGrowth = nLen * 2;
+            sal_Int32 nNewGrowth = _rData.getLength() * 2;
             if ((m_nMaximumResize > 0) && (nNewGrowth > m_nMaximumResize))
             {   // we came to the limit, again ...
                 nNewGrowth = m_nMaximumResize;
-                if (nNewGrowth + nCurrentLength < m_nSize + nLen)
+                if (nNewGrowth + nCurrentLength < m_nSize + _rData.getLength())
                     // but it would not fit if we respect the limit
-                    nNewGrowth = m_nSize + nLen - nCurrentLength;
+                    nNewGrowth = m_nSize + _rData.getLength() - nCurrentLength;
             }
             nNewLength = nCurrentLength + nNewGrowth;
         }
@@ -204,29 +200,33 @@ void SAL_CALL OSequenceOutputStream::writeBytes( const sal_Int8* pStr, sal_Int32
         m_rSequence.realloc(nNewLength);
     }
 
-    OSL_ENSURE(m_rSequence.getLength() >= m_nSize + nLen,
+    OSL_ENSURE(m_rSequence.getLength() >= m_nSize + _rData.getLength(),
         "ooops ... the realloc algorithm seems to be wrong :( !");
 
-    memcpy(m_rSequence.getArray() + m_nSize, pStr, nLen);
-    m_nSize += nLen;
+    memcpy(m_rSequence.getArray() + m_nSize, _rData.getConstArray(), _rData.getLength());
+    m_nSize += _rData.getLength();
 }
 
 
 void SAL_CALL OSequenceOutputStream::flush(  ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception)
 {
+    MutexGuard aGuard(m_aMutex);
     if (!m_bConnected)
         throw NotConnectedException();
 
     // cut the sequence to the real size
     m_rSequence.realloc(m_nSize);
-    // and next time write to the beginning
-    m_nSize = 0;
 }
 
 
 void SAL_CALL OSequenceOutputStream::closeOutput(  ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception)
 {
-    flush();
+    MutexGuard aGuard(m_aMutex);
+    if (!m_bConnected)
+        throw NotConnectedException();
+
+    // cut the sequence to the real size
+    m_rSequence.realloc(m_nSize);
     // and don't allow any further accesses
     m_bConnected = false;
 }
diff --git a/include/comphelper/seqstream.hxx b/include/comphelper/seqstream.hxx
index 1288a9b..d572995 100644
--- a/include/comphelper/seqstream.hxx
+++ b/include/comphelper/seqstream.hxx
@@ -74,21 +74,26 @@ public:
 private:
     inline sal_Int32 avail();
 };
+typedef ::cppu::WeakImplHelper1< ::com::sun::star::io::XOutputStream > OSequenceOutputStream_Base;
 
-class COMPHELPER_DLLPUBLIC OSequenceOutputStream :
-    public ::cppu::WeakImplHelper1< ::com::sun::star::io::XOutputStream >
+class OSequenceOutputStream : public OSequenceOutputStream_Base
 {
 protected:
     ::com::sun::star::uno::Sequence< sal_Int8 >&    m_rSequence;
     double                                          m_nResizeFactor;
     sal_Int32                                       m_nMinimumResize;
     sal_Int32                                       m_nMaximumResize;
-    /** the size of the virtual stream. This is not the size of the sequence,
-        but the number of bytes written into the stream at a given moment.
-     */
     sal_Int32                                       m_nSize;
+        // the size of the virtual stream. This is not the size of the sequence, but the number of bytes written
+        // into the stream at a given moment.
 
-    bool                                            m_bConnected; ///< closeOutput has been called ?
+    bool                                        m_bConnected;
+        // closeOutput has been called ?
+
+    ::osl::Mutex                                    m_aMutex;
+
+protected:
+    virtual ~OSequenceOutputStream() { if (m_bConnected) closeOutput(); }
 
 public:
     /** constructs the object. Everything written into the stream through the XOutputStream methods will be forwarded
@@ -113,20 +118,13 @@ public:
         sal_Int32 _nMaximumResize = -1
         );
 
-    virtual ~OSequenceOutputStream() { if (m_bConnected) closeOutput(); }
-
-    sal_Int32 getSize() const { return m_nSize; }
-
     /// same as XOutputStream::writeBytes (as expected :)
     virtual void SAL_CALL 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, std::exception) SAL_OVERRIDE;
-    void SAL_CALL writeBytes( const sal_Int8* pStr, sal_Int32 nLen )
-        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception);
-    /** Resizes the sequence used for writing to the really used size.
-     *  Next time, writeBytes will write to the beginning of the sequence.
-    */
+    /// this is a dummy in this implementation, no buffering is used
     virtual void SAL_CALL flush(  ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
-    /** Calls flush() and closes the output stream to prevent further manipulation with the sequence.
-        Every subsequent call to one of the XOutputStream methods will throw a <code>NotConnectedException</code>.
+    /** closes the output stream. In the case of this class, this means that the sequence used for writing is
+        resized to the really used size and not used any further, every subsequent call to one of the XOutputStream
+        methods will throw a <code>NotConnectedException</code>.
     */
     virtual void SAL_CALL closeOutput(  ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
 };
commit ea052e766a67c2ae74d0960782c4d5fb335c25e6
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Mon Sep 29 16:16:05 2014 +0200

    FastSerializer: Have own fast cache buffer implementation for XOutputStream
    
    Previously comphelper::OSequenceOutputStream was used.
    
    Change-Id: I4dc38c8c62422e59efa1071312497364cdf5be3c

diff --git a/sax/source/tools/CachedOutputStream.hxx b/sax/source/tools/CachedOutputStream.hxx
new file mode 100644
index 0000000..56b17fb
--- /dev/null
+++ b/sax/source/tools/CachedOutputStream.hxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SAX_SOURCE_TOOLS_CACHEDOUTPUTSTREAM_HXX
+#define INCLUDED_SAX_SOURCE_TOOLS_CACHEDOUTPUTSTREAM_HXX
+
+#include <sal/types.h>
+
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <cstring>
+#include <cstdlib>
+
+namespace sax_fastparser {
+
+class CachedOutputStream
+{
+    /// realloc aligns to this value
+    static const sal_Int32 mnMinimumResize = 0x1000;
+    /// When buffer hits this size, it's written to mxOutputStream
+    static const sal_Int32 mnMaximumSize = 0x10000;
+
+    /// Output stream, usually writing data into files.
+    css::uno::Reference< css::io::XOutputStream > mxOutputStream;
+    sal_Int32 mnCacheAllocatedSize;
+    sal_Int32 mnCacheWrittenSize;
+    sal_Int8* mpCache;
+
+public:
+    CachedOutputStream() : mnCacheAllocatedSize(mnMinimumResize)
+                         , mnCacheWrittenSize(0)
+    {
+        mpCache = static_cast<sal_Int8 *>(malloc(mnCacheAllocatedSize));
+    }
+
+    ~CachedOutputStream()
+    {
+        free(mpCache);
+    }
+
+    css::uno::Reference< css::io::XOutputStream > getOutputStream() const
+    {
+        return mxOutputStream;
+    }
+
+    void setOutputStream( const css::uno::Reference< css::io::XOutputStream >& xOutputStream )
+    {
+        mxOutputStream = xOutputStream;
+    }
+
+    /// cache string and if limit is hit, flush
+    void writeBytes( const sal_Int8* pStr, sal_Int32 nLen )
+    {
+        // Writer does some elements sorting, so it can accumulate
+        // pretty big strings in FastSaxSerializer::ForMerge.
+        // In that case, just flush data and write immediately.
+        if (nLen > mnMaximumSize)
+        {
+            flush();
+            mxOutputStream->writeBytes( css::uno::Sequence<sal_Int8>(pStr, nLen) );
+            return;
+        }
+
+        // Write when the buffer gets big enough
+        if (mnCacheWrittenSize + nLen > mnMaximumSize)
+            flush();
+
+        sal_Int32 nMissingBytes = mnCacheWrittenSize + nLen - mnCacheAllocatedSize;
+        // Ensure the buffer has enough space left
+        if (nMissingBytes > 0)
+        {
+            // Round off to the next multiple of mnMinimumResize
+            mnCacheAllocatedSize = mnCacheAllocatedSize +
+                ((nMissingBytes + mnMinimumResize - 1) / mnMinimumResize) * mnMinimumResize;
+            mpCache = static_cast<sal_Int8 *>(realloc(mpCache, mnCacheAllocatedSize));
+        }
+        assert(mnCacheWrittenSize + nLen <= mnCacheAllocatedSize);
+        memcpy(mpCache + mnCacheWrittenSize, pStr, nLen);
+        mnCacheWrittenSize += nLen;
+    }
+
+    /// immediately write buffer into mxOutputStream and clear
+    void flush()
+    {
+        mxOutputStream->writeBytes( css::uno::Sequence<sal_Int8>(mpCache, mnCacheWrittenSize) );
+        // and next time write to the beginning
+        mnCacheWrittenSize = 0;
+    }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index d6c1a94..02c97e6 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -62,9 +62,7 @@ static const char sXmlHeader[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" stand
 
 namespace sax_fastparser {
     FastSaxSerializer::FastSaxSerializer( )
-        : maOutputData(0x4000)
-        , maOutputStream(maOutputData, 1.3, 0x1000, 0x4000)
-        , mxOutputStream()
+        : maCachedOutputStream()
         , mxFastTokenHandler()
         , maMarkStack()
     {
@@ -116,8 +114,7 @@ namespace sax_fastparser {
 
     void FastSaxSerializer::endDocument()
     {
-        maOutputStream.flush();
-        mxOutputStream->writeBytes(maOutputData);
+        maCachedOutputStream.flush();
     }
 
     void FastSaxSerializer::writeId( ::sal_Int32 nElement )
@@ -197,7 +194,12 @@ namespace sax_fastparser {
 
     void FastSaxSerializer::setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream )
     {
-        mxOutputStream = xOutputStream;
+        maCachedOutputStream.setOutputStream( xOutputStream );
+    }
+
+    ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > FastSaxSerializer::getOutputStream()
+    {
+        return maCachedOutputStream.getOutputStream();
     }
 
     void FastSaxSerializer::setFastTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xFastTokenHandler )
@@ -294,13 +296,7 @@ namespace sax_fastparser {
 
     void FastSaxSerializer::writeOutput( const sal_Int8* pStr, size_t nLen )
     {
-        maOutputStream.writeBytes( pStr, nLen );
-        // Write when the sequence gets big enough
-        if (maOutputStream.getSize() > 0x10000)
-        {
-            maOutputStream.flush();
-            mxOutputStream->writeBytes(maOutputData);
-        }
+        maCachedOutputStream.writeBytes( pStr, nLen );
     }
 
     FastSaxSerializer::Int8Sequence& FastSaxSerializer::ForMerge::getData()
diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx
index 05db2c7..1b541c1 100644
--- a/sax/source/tools/fastserializer.hxx
+++ b/sax/source/tools/fastserializer.hxx
@@ -23,9 +23,9 @@
 #include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
 #include <com/sun/star/io/XOutputStream.hpp>
 
-#include <comphelper/seqstream.hxx>
 #include <sax/fastattribs.hxx>
 #include <sax/fshelper.hxx>
+#include <CachedOutputStream.hxx>
 
 #include <stack>
 #include <map>
@@ -43,7 +43,7 @@ public:
     FastSaxSerializer();
     ~FastSaxSerializer();
 
-    ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > getOutputStream() {return mxOutputStream;}
+    ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > getOutputStream();
 
     /** called by the parser when parsing of an XML stream is started.
      */
@@ -140,12 +140,8 @@ public:
     void mergeTopMarks( sax_fastparser::MergeMarksEnum eMergeType = sax_fastparser::MERGE_MARKS_APPEND );
 
 private:
-    /// Buffer written to mxOutputStream at the end, called from FSHelper destructor.
-    css::uno::Sequence< sal_Int8 > maOutputData;
-    /// Helper class to dynamically allocate memory when needed for maOutputData.
-    comphelper::OSequenceOutputStream maOutputStream;
-    /// Output stream, usually writing data into files.
-    ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > mxOutputStream;
+    /// Helper class to cache data and write in chunks to XOutputStream
+    CachedOutputStream maCachedOutputStream;
     ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxFastTokenHandler;
 
     class ForMerge
@@ -207,7 +203,6 @@ private:
 #endif
 
     void writeFastAttributeList( FastAttributeList* pAttrList );
-    /// Write to maOutputData and if it's big enough flush that to mxOutputStream
     void writeOutput( const sal_Int8* pStr, size_t nLen );
     void writeOutput( const css::uno::Sequence< ::sal_Int8 >& aData );
 
commit 406062334a4891094928149711fcbb98fccc3fff
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Sun Sep 28 00:09:16 2014 +0200

    FastSerializer: avoid some more OStrings
    
    Change-Id: I2d5dbe9adccdd231cc16a1f83a90a4adeb965c64

diff --git a/include/sax/fastattribs.hxx b/include/sax/fastattribs.hxx
index 5255481..85a1218 100644
--- a/include/sax/fastattribs.hxx
+++ b/include/sax/fastattribs.hxx
@@ -87,6 +87,7 @@ public:
     void addUnknown( const OString& rName, const sal_Char* pValue );
     const std::vector< sal_Int32 >&  getFastAttributeTokens() const { return maAttributeTokens; }
     const char* getFastAttributeValue(size_t nIndex) const { return mpChunk + maAttributeValues[nIndex]; }
+    sal_Int32 AttributeValueLength(size_t i) const { return maAttributeValues[i + 1] - maAttributeValues[i] - 1; }
 
     // performance sensitive shortcuts to avoid allocation ...
     bool getAsInteger( sal_Int32 nToken, sal_Int32 &rInt);
@@ -103,9 +104,6 @@ public:
     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::xml::FastAttribute > SAL_CALL getFastAttributes() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
 
 private:
-    inline sal_Int32 AttributeValueLength(sal_Int32 i);
-
-private:
     sal_Char *mpChunk; ///< buffer to store all attribute values - null terminated strings
     sal_Int32 mnChunkLength; ///< size of allocated memory for mpChunk
     // maAttributeValues stores pointers, relative to mpChunk, for each attribute value string
diff --git a/sax/source/tools/fastattribs.cxx b/sax/source/tools/fastattribs.cxx
index 67f3196..e2cbcc6 100644
--- a/sax/source/tools/fastattribs.cxx
+++ b/sax/source/tools/fastattribs.cxx
@@ -225,12 +225,6 @@ Sequence< FastAttribute > FastAttributeList::getFastAttributes(  ) throw (Runtim
     return aSeq;
 }
 
-sal_Int32 FastAttributeList::AttributeValueLength(sal_Int32 i)
-{
-    // Pointers to null terminated strings
-    return maAttributeValues[i + 1] - maAttributeValues[i] - 1;
-}
-
 sal_Int32 FastTokenHandlerBase::getTokenFromChars(
         const css::uno::Reference< css::xml::sax::XFastTokenHandler > &xTokenHandler,
         FastTokenHandlerBase *pTokenHandler,
diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index 3a8b770..d6c1a94 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -83,14 +83,20 @@ namespace sax_fastparser {
 
     void FastSaxSerializer::write( const OString& sOutput, bool bEscape )
     {
+        write( sOutput.getStr(), sOutput.getLength(), bEscape );
+    }
+
+    void FastSaxSerializer::write( const char* pStr, sal_Int32 nLen, bool bEscape )
+    {
+        if (nLen == 0)
+            nLen = strlen(pStr);
+
         if (!bEscape)
         {
-            writeBytes( sOutput.getStr(), sOutput.getLength() );
+            writeBytes( pStr, nLen );
             return;
         }
 
-        const char* pStr = sOutput.getStr();
-        sal_Int32 nLen = sOutput.getLength();
         for (sal_Int32 i = 0; i < nLen; ++i)
         {
             char c = pStr[ i ];
@@ -222,7 +228,7 @@ namespace sax_fastparser {
 
             writeBytes(sEqualSignAndQuote, N_CHARS(sEqualSignAndQuote));
 
-            write(pAttrList->getFastAttributeValue(j), true);
+            write(pAttrList->getFastAttributeValue(j), pAttrList->AttributeValueLength(j), true);
 
             writeBytes(sQuote, N_CHARS(sQuote));
         }
diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx
index 089348a..05db2c7 100644
--- a/sax/source/tools/fastserializer.hxx
+++ b/sax/source/tools/fastserializer.hxx
@@ -105,6 +105,7 @@ public:
 
     void write( const OUString& s, bool bEscape = false );
     void write( const OString& s, bool bEscape = false );
+    void write( const char* pStr, sal_Int32 nLen, bool bEscape = false );
 
 public:
     /** From now on, don't write directly to the stream, but to top of a stack.
diff --git a/sax/source/tools/fshelper.cxx b/sax/source/tools/fshelper.cxx
index 30e5932..c6ac390 100644
--- a/sax/source/tools/fshelper.cxx
+++ b/sax/source/tools/fshelper.cxx
@@ -109,7 +109,8 @@ void FastSerializerHelper::singleElement(sal_Int32 elementTokenId, XFastAttribut
 
 FastSerializerHelper* FastSerializerHelper::write(const char* value)
 {
-    return write(OString(value));
+    mpSerializer->write(value, 0, false);
+    return this;
 }
 
 FastSerializerHelper* FastSerializerHelper::write(const OUString& value)
@@ -141,7 +142,7 @@ FastSerializerHelper* FastSerializerHelper::write(double value)
 
 FastSerializerHelper* FastSerializerHelper::writeEscaped(const char* value)
 {
-    mpSerializer->write(OString(value), true);
+    mpSerializer->write(value, 0, true);
     return this;
 }
 
commit 50d2ffd2a107ae8fd5c3e53f4f75234ad37081ea
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Sat Sep 27 21:46:36 2014 +0200

    FastSerializer: Use FastAttributeList directly to write faster.
    
    Change-Id: I28085d4e060bcf052e6aa97a0822a4d653d7c066

diff --git a/include/sax/fastattribs.hxx b/include/sax/fastattribs.hxx
index 6d9c7a4..5255481 100644
--- a/include/sax/fastattribs.hxx
+++ b/include/sax/fastattribs.hxx
@@ -85,6 +85,8 @@ public:
     void addNS( sal_Int32 nNamespaceToken, sal_Int32 nToken, const OString& rValue );
     void addUnknown( const OUString& rNamespaceURL, const OString& rName, const sal_Char* pValue );
     void addUnknown( const OString& rName, const sal_Char* pValue );
+    const std::vector< sal_Int32 >&  getFastAttributeTokens() const { return maAttributeTokens; }
+    const char* getFastAttributeValue(size_t nIndex) const { return mpChunk + maAttributeValues[nIndex]; }
 
     // performance sensitive shortcuts to avoid allocation ...
     bool getAsInteger( sal_Int32 nToken, sal_Int32 &rInt);
diff --git a/include/sax/fshelper.hxx b/include/sax/fshelper.hxx
index d83ce78..5630910 100644
--- a/include/sax/fshelper.hxx
+++ b/include/sax/fshelper.hxx
@@ -20,9 +20,7 @@
 #ifndef INCLUDED_SAX_FSHELPER_HXX
 #define INCLUDED_SAX_FSHELPER_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>
@@ -185,8 +183,7 @@ private:
     void singleElementInternal(sal_Int32 elementTokenId, ...);
 
     FastSaxSerializer* mpSerializer;
-    com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastTokenHandler> mxTokenHandler;
-
+    FastAttributeList maAttrList;
 };
 
 typedef boost::shared_ptr< FastSerializerHelper > FSHelperPtr;
diff --git a/sax/source/tools/fastattribs.cxx b/sax/source/tools/fastattribs.cxx
index 45887b5..67f3196 100644
--- a/sax/source/tools/fastattribs.cxx
+++ b/sax/source/tools/fastattribs.cxx
@@ -129,7 +129,7 @@ sal_Int32 FastAttributeList::getValueToken( ::sal_Int32 Token ) throw (SAXExcept
         if (maAttributeTokens[i] == Token)
             return FastTokenHandlerBase::getTokenFromChars(
                        mxTokenHandler, mpTokenHandler,
-                       mpChunk + maAttributeValues[ i ],
+                       getFastAttributeValue(i),
                        AttributeValueLength( i ) );
 
     throw SAXException();
@@ -141,7 +141,7 @@ sal_Int32 FastAttributeList::getOptionalValueToken( ::sal_Int32 Token, ::sal_Int
         if (maAttributeTokens[i] == Token)
             return FastTokenHandlerBase::getTokenFromChars(
                        mxTokenHandler, mpTokenHandler,
-                       mpChunk + maAttributeValues[ i ],
+                       getFastAttributeValue(i),
                        AttributeValueLength( i ) );
 
     return Default;
@@ -154,7 +154,7 @@ bool FastAttributeList::getAsInteger( sal_Int32 nToken, sal_Int32 &rInt)
     for (size_t i = 0; i < maAttributeTokens.size(); ++i)
         if (maAttributeTokens[i] == nToken)
         {
-            rInt = rtl_str_toInt32( mpChunk + maAttributeValues[i], 10 );
+            rInt = rtl_str_toInt32( getFastAttributeValue(i), 10 );
             return true;
         }
     return false;
@@ -166,7 +166,7 @@ bool FastAttributeList::getAsDouble( sal_Int32 nToken, double &rDouble)
     for (size_t i = 0; i < maAttributeTokens.size(); ++i)
         if (maAttributeTokens[i] == nToken)
         {
-            rDouble = rtl_str_toDouble( mpChunk + maAttributeValues[i] );
+            rDouble = rtl_str_toDouble( getFastAttributeValue(i) );
             return true;
         }
     return false;
@@ -191,7 +191,7 @@ OUString FastAttributeList::getValue( ::sal_Int32 Token ) throw (SAXException, R
 {
     for (size_t i = 0; i < maAttributeTokens.size(); ++i)
         if (maAttributeTokens[i] == Token)
-            return OUString( mpChunk + maAttributeValues[i], AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
+            return OUString( getFastAttributeValue(i), AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
 
     throw SAXException();
 }
@@ -200,7 +200,7 @@ OUString FastAttributeList::getOptionalValue( ::sal_Int32 Token ) throw (Runtime
 {
     for (size_t i = 0; i < maAttributeTokens.size(); ++i)
         if (maAttributeTokens[i] == Token)
-            return OUString( mpChunk + maAttributeValues[i], AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
+            return OUString( getFastAttributeValue(i), AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
 
     return OUString();
 }
@@ -219,7 +219,7 @@ Sequence< FastAttribute > FastAttributeList::getFastAttributes(  ) throw (Runtim
     for (size_t i = 0; i < maAttributeTokens.size(); ++i)
     {
         pAttr->Token = maAttributeTokens[i];
-        pAttr->Value = OUString( mpChunk + maAttributeValues[i], AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
+        pAttr->Value = OUString( getFastAttributeValue(i), AttributeValueLength(i), RTL_TEXTENCODING_UTF8 );
         pAttr++;
     }
     return aSeq;
diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index f2f8bc6..3a8b770 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -21,7 +21,6 @@
 
 #include <com/sun/star/xml/Attribute.hpp>
 #include <com/sun/star/xml/FastAttribute.hpp>
-#include <com/sun/star/xml/sax/XFastAttributeList.hpp>
 
 #include <rtl/ustrbuf.hxx>
 #include <comphelper/sequenceasvector.hxx>
@@ -40,7 +39,6 @@ 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::io::XOutputStream;
 using ::com::sun::star::io::NotConnectedException;
 using ::com::sun::star::io::IOException;
@@ -145,7 +143,7 @@ namespace sax_fastparser {
     }
 #endif
 
-    void FastSaxSerializer::startFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs )
+    void FastSaxSerializer::startFastElement( ::sal_Int32 Element, FastAttributeList* pAttrList )
     {
         if ( !maMarkStack.empty() )
             maMarkStack.top()->setCurrentElement( Element );
@@ -157,7 +155,7 @@ namespace sax_fastparser {
         writeBytes(sOpeningBracket, N_CHARS(sOpeningBracket));
 
         writeId(Element);
-        writeFastAttributeList(Attribs);
+        writeFastAttributeList(pAttrList);
 
         writeBytes(sClosingBracket, N_CHARS(sClosingBracket));
     }
@@ -178,7 +176,7 @@ namespace sax_fastparser {
         writeBytes(sClosingBracket, N_CHARS(sClosingBracket));
     }
 
-    void FastSaxSerializer::singleFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs )
+    void FastSaxSerializer::singleFastElement( ::sal_Int32 Element, FastAttributeList* pAttrList )
     {
         if ( !maMarkStack.empty() )
             maMarkStack.top()->setCurrentElement( Element );
@@ -186,7 +184,7 @@ namespace sax_fastparser {
         writeBytes(sOpeningBracket, N_CHARS(sOpeningBracket));
 
         writeId(Element);
-        writeFastAttributeList(Attribs);
+        writeFastAttributeList(pAttrList);
 
         writeBytes(sSlashAndClosingBracket, N_CHARS(sSlashAndClosingBracket));
     }
@@ -200,38 +198,18 @@ namespace sax_fastparser {
     {
         mxFastTokenHandler = xFastTokenHandler;
     }
-    void FastSaxSerializer::writeFastAttributeList( const Reference< XFastAttributeList >& Attribs )
+
+    void FastSaxSerializer::writeFastAttributeList( FastAttributeList* pAttrList )
     {
 #ifdef DBG_UTIL
         ::std::set<OUString> DebugAttributes;
 #endif
-        Sequence< Attribute > aAttrSeq = Attribs->getUnknownAttributes();
-        const Attribute *pAttr = aAttrSeq.getConstArray();
-        sal_Int32 nAttrLength = aAttrSeq.getLength();
-        for (sal_Int32 i = 0; i < nAttrLength; i++)
-        {
-            writeBytes(sSpace, N_CHARS(sSpace));
-
-            OUString const& rAttrName(pAttr[i].Name);
-#ifdef DBG_UTIL
-            // Well-formedness constraint: Unique Att Spec
-            assert(DebugAttributes.find(rAttrName) == DebugAttributes.end());
-            DebugAttributes.insert(rAttrName);
-#endif
-            write(rAttrName);
-            writeBytes(sEqualSignAndQuote, N_CHARS(sEqualSignAndQuote));
-            write(pAttr[i].Value, true);
-            writeBytes(sQuote, N_CHARS(sQuote));
-        }
-
-        Sequence< FastAttribute > aFastAttrSeq = Attribs->getFastAttributes();
-        const FastAttribute *pFastAttr = aFastAttrSeq.getConstArray();
-        sal_Int32 nFastAttrLength = aFastAttrSeq.getLength();
-        for (sal_Int32 j = 0; j < nFastAttrLength; j++)
+        const std::vector< sal_Int32 >& Tokens = pAttrList->getFastAttributeTokens();
+        for (size_t j = 0; j < Tokens.size(); j++)
         {
             writeBytes(sSpace, N_CHARS(sSpace));
 
-            sal_Int32 nToken = pFastAttr[j].Token;
+            sal_Int32 nToken = Tokens[j];
             writeId(nToken);
 
 #ifdef DBG_UTIL
@@ -244,7 +222,7 @@ namespace sax_fastparser {
 
             writeBytes(sEqualSignAndQuote, N_CHARS(sEqualSignAndQuote));
 
-            write(pFastAttr[j].Value, true);
+            write(pAttrList->getFastAttributeValue(j), true);
 
             writeBytes(sQuote, N_CHARS(sQuote));
         }
diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx
index 82e9eea..089348a 100644
--- a/sax/source/tools/fastserializer.hxx
+++ b/sax/source/tools/fastserializer.hxx
@@ -22,16 +22,15 @@
 
 #include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
 #include <com/sun/star/io/XOutputStream.hpp>
-#include <rtl/byteseq.hxx>
+
+#include <comphelper/seqstream.hxx>
+#include <sax/fastattribs.hxx>
+#include <sax/fshelper.hxx>
 
 #include <stack>
 #include <map>
-
 #include <boost/shared_ptr.hpp>
 
-#include <comphelper/seqstream.hxx>
-#include "sax/fshelper.hxx"
-
 namespace sax_fastparser {
 
 /// Receives notification of sax document events to write into an XOutputStream.
@@ -67,11 +66,11 @@ public:
             <b>or</b> operation.
 
         @param Attribs
-            Contains a <type>XFastAttrbitueList</type> to access the attributes
+            Contains a <type>FastAttributeList</type> to access the attributes
             from the element.
 
     */
-    void startFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
+    void startFastElement( ::sal_Int32 Element, FastAttributeList* Attribs );
 
     /** receives notification of the end of an known element.
         @see startFastElement
@@ -91,11 +90,11 @@ public:
             <b>or</b> operation.
 
         @param Attribs
-            Contains a <type>XFastAttrbitueList</type> to access the attributes
+            Contains a <type>FastAttributeList</type> to access the attributes
             from the element.
 
     */
-    void singleFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
+    void singleFastElement( ::sal_Int32 Element, FastAttributeList* Attribs );
 
     void setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream );
     void setFastTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xFastTokenHandler );
@@ -206,7 +205,7 @@ private:
     ::std::stack<sal_Int32> m_DebugStartedElements;
 #endif
 
-    void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
+    void writeFastAttributeList( FastAttributeList* pAttrList );
     /// Write to maOutputData and if it's big enough flush that to mxOutputStream
     void writeOutput( const sal_Int8* pStr, size_t nLen );
     void writeOutput( const css::uno::Sequence< ::sal_Int8 >& aData );
diff --git a/sax/source/tools/fshelper.cxx b/sax/source/tools/fshelper.cxx
index 0e5df28..30e5932 100644
--- a/sax/source/tools/fshelper.cxx
+++ b/sax/source/tools/fshelper.cxx
@@ -20,6 +20,7 @@
 #include <sax/fshelper.hxx>
 #include "fastserializer.hxx"
 #include <com/sun/star/xml/sax/FastTokenHandler.hpp>
+#include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
 #include <comphelper/processfactory.hxx>
 #include <rtl/ustrbuf.hxx>
 
@@ -30,11 +31,10 @@ namespace sax_fastparser {
 
 FastSerializerHelper::FastSerializerHelper(const Reference< io::XOutputStream >& xOutputStream, bool bWriteHeader ) :
     mpSerializer(new FastSaxSerializer())
+  , maAttrList(Reference< xml::sax::XFastTokenHandler >())
 {
     Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext(), UNO_SET_THROW );
-    mxTokenHandler = css::xml::sax::FastTokenHandler::create(xContext);
-
-    mpSerializer->setFastTokenHandler( mxTokenHandler );
+    mpSerializer->setFastTokenHandler( css::xml::sax::FastTokenHandler::create(xContext) );
     assert(xOutputStream.is()); // cannot do anything without that
     mpSerializer->setOutputStream( xOutputStream );
     if( bWriteHeader )
@@ -51,7 +51,7 @@ void FastSerializerHelper::startElementInternal(sal_Int32 elementTokenId, ...)
 {
     va_list args;
     va_start( args, elementTokenId );
-    FastAttributeList* pAttrList = new FastAttributeList( mxTokenHandler );
+    maAttrList.clear();
 
     while (true)
     {
@@ -60,11 +60,10 @@ void FastSerializerHelper::startElementInternal(sal_Int32 elementTokenId, ...)
             break;
         const char* pValue = va_arg(args, const char*);
         if (pValue)
-            pAttrList->add(nName, pValue);
+            maAttrList.add(nName, pValue);
     }
 
-    const com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastAttributeList> xAttrList(pAttrList);
-    mpSerializer->startFastElement(elementTokenId, xAttrList);
+    mpSerializer->startFastElement(elementTokenId, &maAttrList);
     va_end( args );
 }
 
@@ -72,7 +71,7 @@ void FastSerializerHelper::singleElementInternal(sal_Int32 elementTokenId, ...)
 {
     va_list args;
     va_start( args, elementTokenId );
-    FastAttributeList* pAttrList = new FastAttributeList( mxTokenHandler );
+    maAttrList.clear();
 
     while (true)
     {
@@ -81,11 +80,10 @@ void FastSerializerHelper::singleElementInternal(sal_Int32 elementTokenId, ...)
             break;
         const char* pValue = va_arg(args, const char*);
         if  (pValue)
-            pAttrList->add(nName, pValue);
+            maAttrList.add(nName, pValue);
     }
 
-    const com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastAttributeList> xAttrList(pAttrList);
-    mpSerializer->singleFastElement(elementTokenId, xAttrList);
+    mpSerializer->singleFastElement(elementTokenId, &maAttrList);
     va_end( args );
 }
 
@@ -96,13 +94,17 @@ void FastSerializerHelper::endElement(sal_Int32 elementTokenId)
 
 void FastSerializerHelper::startElement(sal_Int32 elementTokenId, XFastAttributeListRef xAttrList)
 {
-    mpSerializer->startFastElement(elementTokenId, xAttrList);
+    FastAttributeList* pAttrList = dynamic_cast< FastAttributeList* >(xAttrList.get());
+    assert(pAttrList);
+    mpSerializer->startFastElement(elementTokenId, pAttrList);
 }
 
 
 void FastSerializerHelper::singleElement(sal_Int32 elementTokenId, XFastAttributeListRef xAttrList)
 {
-    mpSerializer->singleFastElement(elementTokenId, xAttrList);
+    FastAttributeList* pAttrList = dynamic_cast< FastAttributeList* >(xAttrList.get());
+    assert(pAttrList);
+    mpSerializer->singleFastElement(elementTokenId, pAttrList);
 }
 
 FastSerializerHelper* FastSerializerHelper::write(const char* value)
@@ -172,7 +174,7 @@ void FastSerializerHelper::mergeTopMarks( MergeMarksEnum eMergeType )
 
 FastAttributeList * FastSerializerHelper::createAttrList()
 {
-    return new FastAttributeList( mxTokenHandler );
+    return new FastAttributeList( Reference< xml::sax::XFastTokenHandler >() );
 }
 
 
commit e1c503a2e3309d9f738d7f702a562509899fdb3f
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Sep 26 10:37:17 2014 +0100

    fastparser: avoid allocating un-used FastTokenLookup class.
    
    This contained an rtl_Sequence complete with horror internal
    allocator, caught red-handed serializing threaded loading to no
    good purpose.
    
    Change-Id: I837b2c17e4f70fd6a49bed33ad74a7d79f98f35c

diff --git a/include/sax/fastattribs.hxx b/include/sax/fastattribs.hxx
index 4724b7e..6d9c7a4 100644
--- a/include/sax/fastattribs.hxx
+++ b/include/sax/fastattribs.hxx
@@ -52,22 +52,24 @@ typedef std::vector< UnknownAttribute > UnknownAttributeList;
 /// A native C++ interface to tokenisation
 class SAX_DLLPUBLIC FastTokenHandlerBase
 {
-    public:
-        virtual ~FastTokenHandlerBase();
-        virtual sal_Int32 getTokenDirect( const char *pToken, sal_Int32 nLength ) const = 0;
-};
-
-/// avoid constantly allocating and freeing sequences.
-class SAX_DLLPUBLIC FastTokenLookup
-{
-    static const int mnUtf8BufferSize = 128;
-    css::uno::Sequence< sal_Int8 > maUtf8Buffer;
-public:
-    FastTokenLookup();
-    sal_Int32 getTokenFromChars(
-        const css::uno::Reference< css::xml::sax::XFastTokenHandler > &mxTokenHandler,
-        FastTokenHandlerBase *pTokenHandler,
-        const char *pStr, size_t nLength = 0 );
+ public:
+    virtual ~FastTokenHandlerBase();
+    virtual sal_Int32 getTokenDirect( const char *pToken, sal_Int32 nLength ) const = 0;
+
+    /**
+     * Client method to attempt the use of this interface if possible.
+     * @xTokenHandler - the UNO handle for the token lookup interface
+     * @pTokenHandler - a dynamic_cast version of @xTokenHandler to this interface
+     * @pStr - string buffer to lookup
+     * @nLength - optional length of chars in that buffer
+     *
+     * @return Tokenized form of pStr
+     */
+    static sal_Int32 getTokenFromChars(
+                         const css::uno::Reference<
+                             css::xml::sax::XFastTokenHandler > &xTokenHandler,
+                         FastTokenHandlerBase *pTokenHandler /* can be NULL */,
+                         const char *pStr, size_t nLength = 0 );
 };
 
 class SAX_DLLPUBLIC FastAttributeList : public ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastAttributeList >
@@ -112,8 +114,6 @@ private:
     UnknownAttributeList maUnknownAttributes;
     ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxTokenHandler;
     FastTokenHandlerBase *mpTokenHandler;
-
-    FastTokenLookup maTokenLookup;
 };
 
 }
diff --git a/sax/source/fastparser/fastparser.cxx b/sax/source/fastparser/fastparser.cxx
index fcbb58d..12429be 100644
--- a/sax/source/fastparser/fastparser.cxx
+++ b/sax/source/fastparser/fastparser.cxx
@@ -253,7 +253,6 @@ private:
 
     Entity *mpTop;                          /// std::stack::top() is amazingly slow => cache this.
     ::std::stack< Entity > maEntities;      /// Entity stack for each call of parseStream().
-    FastTokenLookup maTokenLookup;
 };
 
 } // namespace sax_fastparser
@@ -646,9 +645,9 @@ void FastSaxParserImpl::DefineNamespace( const OString& rPrefix, const sal_Char*
 
 sal_Int32 FastSaxParserImpl::GetToken( const sal_Char* pToken, sal_Int32 nLen /* = 0 */ )
 {
-    return maTokenLookup.getTokenFromChars( getEntity().mxTokenHandler,
-                                            getEntity().mpTokenHandler,
-                                            pToken, nLen );
+    return FastTokenHandlerBase::getTokenFromChars( getEntity().mxTokenHandler,
+                                                    getEntity().mpTokenHandler,
+                                                    pToken, nLen );
 }
 
 sal_Int32 FastSaxParserImpl::GetTokenWithPrefix( const sal_Char*pPrefix, int nPrefixLen, const sal_Char* pName, int nNameLen ) throw (SAXException)
diff --git a/sax/source/tools/fastattribs.cxx b/sax/source/tools/fastattribs.cxx
index 9d03772..45887b5 100644
--- a/sax/source/tools/fastattribs.cxx
+++ b/sax/source/tools/fastattribs.cxx
@@ -127,9 +127,10 @@ sal_Int32 FastAttributeList::getValueToken( ::sal_Int32 Token ) throw (SAXExcept
 {
     for (size_t i = 0; i < maAttributeTokens.size(); ++i)
         if (maAttributeTokens[i] == Token)
-            return maTokenLookup.getTokenFromChars( mxTokenHandler, mpTokenHandler,
-                                                    mpChunk + maAttributeValues[ i ],
-                                                    AttributeValueLength( i ) );
+            return FastTokenHandlerBase::getTokenFromChars(
+                       mxTokenHandler, mpTokenHandler,
+                       mpChunk + maAttributeValues[ i ],
+                       AttributeValueLength( i ) );
 
     throw SAXException();
 }
@@ -138,9 +139,10 @@ sal_Int32 FastAttributeList::getOptionalValueToken( ::sal_Int32 Token, ::sal_Int
 {
     for (size_t i = 0; i < maAttributeTokens.size(); ++i)
         if (maAttributeTokens[i] == Token)
-            return maTokenLookup.getTokenFromChars( mxTokenHandler, mpTokenHandler,
-                                                    mpChunk + maAttributeValues[ i ],
-                                                    AttributeValueLength( i ) );
+            return FastTokenHandlerBase::getTokenFromChars(
+                       mxTokenHandler, mpTokenHandler,
+                       mpChunk + maAttributeValues[ i ],
+                       AttributeValueLength( i ) );
 
     return Default;
 }
@@ -229,16 +231,7 @@ sal_Int32 FastAttributeList::AttributeValueLength(sal_Int32 i)
     return maAttributeValues[i + 1] - maAttributeValues[i] - 1;
 }
 
-FastTokenLookup::FastTokenLookup()
-{
-    maUtf8Buffer.realloc( mnUtf8BufferSize );
-}
-
-/**
- * Avoid doing any memory allocation if we can, instead keep a
- * pet sequence around and do some heavy petting on it.
- */
-sal_Int32 FastTokenLookup::getTokenFromChars(
+sal_Int32 FastTokenHandlerBase::getTokenFromChars(
         const css::uno::Reference< css::xml::sax::XFastTokenHandler > &xTokenHandler,
         FastTokenHandlerBase *pTokenHandler,
         const char *pToken, size_t nLen /* = 0 */ )
commit b98b477c084c876a3a65583dbfed5c1f5f8bfe12
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Sat Sep 27 22:04:13 2014 +0200

    FastSerializer: Remove throw specs; this is not UNO implementation
    
    Change-Id: I462f8ed89de48174ed7aa6e008709963bec50649

diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index 455df0b..f2f8bc6 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -18,14 +18,14 @@
  */
 
 #include "fastserializer.hxx"
-#include <rtl/ustrbuf.hxx>
-
-#include <comphelper/sequenceasvector.hxx>
 
 #include <com/sun/star/xml/Attribute.hpp>
 #include <com/sun/star/xml/FastAttribute.hpp>
 #include <com/sun/star/xml/sax/XFastAttributeList.hpp>
 
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/sequenceasvector.hxx>
+
 #include <string.h>
 
 #if OSL_DEBUG_LEVEL > 0
@@ -73,7 +73,7 @@ namespace sax_fastparser {
     }
     FastSaxSerializer::~FastSaxSerializer() {}
 
-    void SAL_CALL FastSaxSerializer::startDocument(  ) throw (SAXException, RuntimeException)
+    void FastSaxSerializer::startDocument()
     {
         writeBytes(sXmlHeader, N_CHARS(sXmlHeader));
     }
@@ -110,13 +110,13 @@ namespace sax_fastparser {
         }
     }
 
-    void SAL_CALL FastSaxSerializer::endDocument(  ) throw (SAXException, RuntimeException)
+    void FastSaxSerializer::endDocument()
     {
         maOutputStream.flush();
         mxOutputStream->writeBytes(maOutputData);
     }
 
-    void SAL_CALL FastSaxSerializer::writeId( ::sal_Int32 nElement )
+    void FastSaxSerializer::writeId( ::sal_Int32 nElement )
     {
         if( HAS_NAMESPACE( nElement ) ) {
             writeBytes(mxFastTokenHandler->getUTF8Identifier(NAMESPACE(nElement)));
@@ -127,7 +127,7 @@ namespace sax_fastparser {
     }
 
 #ifdef DBG_UTIL
-    OString SAL_CALL FastSaxSerializer::getId( ::sal_Int32 nElement )
+    OString FastSaxSerializer::getId( ::sal_Int32 nElement )
     {
         if (HAS_NAMESPACE(nElement)) {
             Sequence<sal_Int8> const ns(
@@ -145,8 +145,7 @@ namespace sax_fastparser {
     }
 #endif
 
-    void SAL_CALL FastSaxSerializer::startFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs )
-        throw (SAXException, RuntimeException)
+    void FastSaxSerializer::startFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs )
     {
         if ( !maMarkStack.empty() )
             maMarkStack.top()->setCurrentElement( Element );
@@ -163,8 +162,7 @@ namespace sax_fastparser {
         writeBytes(sClosingBracket, N_CHARS(sClosingBracket));
     }
 
-    void SAL_CALL FastSaxSerializer::endFastElement( ::sal_Int32 Element )
-        throw (SAXException, RuntimeException)
+    void FastSaxSerializer::endFastElement( ::sal_Int32 Element )
     {
 #ifdef DBG_UTIL
         assert(!m_DebugStartedElements.empty());
@@ -180,8 +178,7 @@ namespace sax_fastparser {
         writeBytes(sClosingBracket, N_CHARS(sClosingBracket));
     }
 
-    void SAL_CALL FastSaxSerializer::singleFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs )
-        throw (SAXException, RuntimeException)
+    void FastSaxSerializer::singleFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs )
     {
         if ( !maMarkStack.empty() )
             maMarkStack.top()->setCurrentElement( Element );
@@ -194,14 +191,12 @@ namespace sax_fastparser {
         writeBytes(sSlashAndClosingBracket, N_CHARS(sSlashAndClosingBracket));
     }
 
-    void SAL_CALL FastSaxSerializer::setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream )
-        throw (::com::sun::star::uno::RuntimeException)
+    void FastSaxSerializer::setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream )
     {
         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)
+    void FastSaxSerializer::setFastTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xFastTokenHandler )
     {
         mxFastTokenHandler = xFastTokenHandler;
     }
@@ -295,13 +290,11 @@ namespace sax_fastparser {
     }
 
     void FastSaxSerializer::writeBytes( const Sequence< sal_Int8 >& rData )
-        throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     {
         writeBytes( reinterpret_cast<const char*>(rData.getConstArray()), rData.getLength() );
     }
 
     void FastSaxSerializer::writeBytes( const char* pStr, size_t nLen )
-        throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     {
         if ( maMarkStack.empty() )
             writeOutput( reinterpret_cast<const sal_Int8*>(pStr), nLen );
@@ -310,13 +303,12 @@ namespace sax_fastparser {
                 reinterpret_cast<const sal_Int8*>(pStr), nLen) );
     }
 
-    void FastSaxSerializer::writeOutput( const Sequence< ::sal_Int8 >& aData ) throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
+    void FastSaxSerializer::writeOutput( const Sequence< ::sal_Int8 >& aData )
     {
         writeOutput( aData.getConstArray(), aData.getLength() );
     }
 
     void FastSaxSerializer::writeOutput( const sal_Int8* pStr, size_t nLen )
-        throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     {
         maOutputStream.writeBytes( pStr, nLen );
         // Write when the sequence gets big enough
diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx
index b84c1cc..82e9eea 100644
--- a/sax/source/tools/fastserializer.hxx
+++ b/sax/source/tools/fastserializer.hxx
@@ -41,18 +41,18 @@ class FastSaxSerializer
     typedef ::com::sun::star::uno::Sequence< ::sal_Int32 > Int32Sequence;
 
 public:
-    explicit FastSaxSerializer();
+    FastSaxSerializer();
     ~FastSaxSerializer();
 
     ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > getOutputStream() {return mxOutputStream;}
 
     /** called by the parser when parsing of an XML stream is started.
      */
-    void SAL_CALL startDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    void startDocument();
 
     /** called by the parser after the last XML element of a stream is processed.
      */
-    void SAL_CALL endDocument(  ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    void endDocument();
 
     /** receives notification of the beginning of an element.
 
@@ -71,14 +71,12 @@ public:
             from the element.
 
     */
-    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);
+    void startFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
 
     /** receives notification of the end of an known element.
         @see startFastElement
      */
-    void SAL_CALL endFastElement( ::sal_Int32 Element )
-        throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
+    void endFastElement( ::sal_Int32 Element );
 
     /** receives notification of the beginning of a single element.
 
@@ -97,18 +95,14 @@ public:
             from the element.
 
     */
-    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);
+    void singleFastElement( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
 
-    void SAL_CALL setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream )
-        throw (::com::sun::star::uno::RuntimeException);
-
-    void SAL_CALL setFastTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xFastTokenHandler )
-        throw (::com::sun::star::uno::RuntimeException);
+    void setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream );
+    void setFastTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xFastTokenHandler );
 
     // C++ helpers
-    void SAL_CALL writeId( ::sal_Int32 Element );
-    OString SAL_CALL getId( ::sal_Int32 Element );
+    void writeId( ::sal_Int32 Element );
+    OString getId( ::sal_Int32 Element );
 
     void write( const OUString& s, bool bEscape = false );
     void write( const OString& s, bool bEscape = false );
@@ -214,17 +208,15 @@ private:
 
     void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
     /// Write to maOutputData and if it's big enough flush that to mxOutputStream
-    void writeOutput( const sal_Int8* pStr, size_t nLen )
-        throw (css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException);
-    void writeOutput( const css::uno::Sequence< ::sal_Int8 >& aData )
-        throw (css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException);
+    void writeOutput( const sal_Int8* pStr, size_t nLen );
+    void writeOutput( const css::uno::Sequence< ::sal_Int8 >& aData );
 
     /** 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);
-    void writeBytes( const char* pStr, size_t nLen ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+    void writeBytes( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData );
+    void writeBytes( const char* pStr, size_t nLen );
 };
 
 } // namespace sax_fastparser
commit 20538c25129ebadfa2050c0071887e1e2a46c838
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Fri Sep 26 17:17:50 2014 +0200

    FastSerializer: Avoid sequences where possible
    
    Change-Id: I359ca9d3b766b71904e4199ebfbdbd5b203775cc

diff --git a/comphelper/source/streaming/seqstream.cxx b/comphelper/source/streaming/seqstream.cxx
index aec4519..91fdc7d7 100644
--- a/comphelper/source/streaming/seqstream.cxx
+++ b/comphelper/source/streaming/seqstream.cxx
@@ -156,14 +156,19 @@ OSequenceOutputStream::OSequenceOutputStream(Sequence< sal_Int8 >& _rSeq, double
         // this heuristic is as good as any other ... supply better parameters if you don't like it :)
 }
 
-
 void SAL_CALL OSequenceOutputStream::writeBytes( const Sequence< sal_Int8 >& _rData ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception)
 {
+    writeBytes(_rData.getConstArray(), _rData.getLength());
+}
+
+void SAL_CALL OSequenceOutputStream::writeBytes( const sal_Int8* pStr, sal_Int32 nLen )
+    throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception)
+{
     if (!m_bConnected)
         throw NotConnectedException();
 
     // ensure the sequence has enough space left
-    if (m_nSize + _rData.getLength() > m_rSequence.getLength())
+    if (m_nSize + nLen > m_rSequence.getLength())
     {
         sal_Int32 nCurrentLength = m_rSequence.getLength();
         sal_Int32 nNewLength = static_cast< sal_Int32 >(
@@ -177,18 +182,18 @@ void SAL_CALL OSequenceOutputStream::writeBytes( const Sequence< sal_Int8 >& _rD
             // such a large step is not allowed
             nNewLength = nCurrentLength + m_nMaximumResize;
 
-        if (nNewLength < m_nSize + _rData.getLength())
+        if (nNewLength < m_nSize + nLen)
         {   // it's not enough .... the data would not fit
 
             // let's take the double amount of the length of the data to be written, as the next write
             // request could be as large as this one
-            sal_Int32 nNewGrowth = _rData.getLength() * 2;
+            sal_Int32 nNewGrowth = nLen * 2;
             if ((m_nMaximumResize > 0) && (nNewGrowth > m_nMaximumResize))
             {   // we came to the limit, again ...
                 nNewGrowth = m_nMaximumResize;
-                if (nNewGrowth + nCurrentLength < m_nSize + _rData.getLength())
+                if (nNewGrowth + nCurrentLength < m_nSize + nLen)
                     // but it would not fit if we respect the limit
-                    nNewGrowth = m_nSize + _rData.getLength() - nCurrentLength;
+                    nNewGrowth = m_nSize + nLen - nCurrentLength;
             }
             nNewLength = nCurrentLength + nNewGrowth;
         }
@@ -199,11 +204,11 @@ void SAL_CALL OSequenceOutputStream::writeBytes( const Sequence< sal_Int8 >& _rD
         m_rSequence.realloc(nNewLength);
     }
 
-    OSL_ENSURE(m_rSequence.getLength() >= m_nSize + _rData.getLength(),
+    OSL_ENSURE(m_rSequence.getLength() >= m_nSize + nLen,
         "ooops ... the realloc algorithm seems to be wrong :( !");
 
-    memcpy(m_rSequence.getArray() + m_nSize, _rData.getConstArray(), _rData.getLength());
-    m_nSize += _rData.getLength();
+    memcpy(m_rSequence.getArray() + m_nSize, pStr, nLen);
+    m_nSize += nLen;
 }
 
 
diff --git a/include/comphelper/seqstream.hxx b/include/comphelper/seqstream.hxx
index 75b1934..1288a9b 100644
--- a/include/comphelper/seqstream.hxx
+++ b/include/comphelper/seqstream.hxx
@@ -119,6 +119,8 @@ public:
 
     /// same as XOutputStream::writeBytes (as expected :)
     virtual void SAL_CALL 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, std::exception) SAL_OVERRIDE;
+    void SAL_CALL writeBytes( const sal_Int8* pStr, sal_Int32 nLen )
+        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception);
     /** Resizes the sequence used for writing to the really used size.
      *  Next time, writeBytes will write to the beginning of the sequence.
     */
diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index 300c0d3..455df0b 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -37,7 +37,6 @@ using ::comphelper::SequenceAsVector;
 using ::com::sun::star::uno::Reference;
 using ::com::sun::star::uno::RuntimeException;
 using ::com::sun::star::uno::Sequence;
-using ::com::sun::star::uno::toUnoSequence;
 using ::com::sun::star::xml::FastAttribute;
 using ::com::sun::star::xml::Attribute;
 using ::com::sun::star::xml::sax::SAXException;
@@ -50,6 +49,18 @@ using ::com::sun::star::io::BufferSizeExceededException;
 #define HAS_NAMESPACE(x) ((x & 0xffff0000) != 0)
 #define NAMESPACE(x) (x >> 16)
 #define TOKEN(x) (x & 0xffff)
+// number of characters without terminating 0
+#define N_CHARS(string) (SAL_N_ELEMENTS(string) - 1)
+
+static const char sClosingBracket[] = ">";
+static const char sSlashAndClosingBracket[] = "/>";
+static const char sColon[] = ":";
+static const char sOpeningBracket[] = "<";
+static const char sOpeningBracketAndSlash[] = "</";
+static const char sQuote[] = "\"";
+static const char sEqualSignAndQuote[] = "=\"";
+static const char sSpace[] = " ";
+static const char sXmlHeader[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
 
 namespace sax_fastparser {
     FastSaxSerializer::FastSaxSerializer( )
@@ -58,22 +69,13 @@ namespace sax_fastparser {
         , mxOutputStream()
         , mxFastTokenHandler()
         , maMarkStack()
-        , maClosingBracket((const sal_Int8 *)">", 1)
-        , maSlashAndClosingBracket((const sal_Int8 *)"/>", 2)
-        , maColon((const sal_Int8 *)":", 1)
-        , maOpeningBracket((const sal_Int8 *)"<", 1)
-        , maOpeningBracketAndSlash((const sal_Int8 *)"</", 2)
-        , maQuote((const sal_Int8 *)"\"", 1)
-        , maEqualSignAndQuote((const sal_Int8 *)"=\"", 2)
-        , maSpace((const sal_Int8 *)" ", 1)
     {
     }
     FastSaxSerializer::~FastSaxSerializer() {}
 
     void SAL_CALL FastSaxSerializer::startDocument(  ) throw (SAXException, RuntimeException)
     {
-        rtl::ByteSequence aXmlHeader((const sal_Int8*) "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n", 56);
-        writeBytes(toUnoSequence(aXmlHeader));
+        writeBytes(sXmlHeader, N_CHARS(sXmlHeader));
     }
 
     void FastSaxSerializer::write( const OUString& sOutput, bool bEscape )
@@ -118,7 +120,7 @@ namespace sax_fastparser {
     {
         if( HAS_NAMESPACE( nElement ) ) {
             writeBytes(mxFastTokenHandler->getUTF8Identifier(NAMESPACE(nElement)));
-            writeBytes(toUnoSequence(maColon));
+            writeBytes(sColon, N_CHARS(sColon));
             writeBytes(mxFastTokenHandler->getUTF8Identifier(TOKEN(nElement)));
         } else
             writeBytes(mxFastTokenHandler->getUTF8Identifier(nElement));
@@ -133,7 +135,7 @@ namespace sax_fastparser {
             Sequence<sal_Int8> const name(
                 mxFastTokenHandler->getUTF8Identifier(TOKEN(nElement)));
             return OString(reinterpret_cast<sal_Char const*>(ns.getConstArray()), ns.getLength())
-                 + OString(reinterpret_cast<sal_Char const*>(maColon.getConstArray()), maColon.getLength())
+                 + OString(sColon, N_CHARS(sColon))
                  + OString(reinterpret_cast<sal_Char const*>(name.getConstArray()), name.getLength());
         } else {
             Sequence<sal_Int8> const name(
@@ -153,12 +155,12 @@ namespace sax_fastparser {
         m_DebugStartedElements.push(Element);
 #endif
 
-        writeBytes(toUnoSequence(maOpeningBracket));
+        writeBytes(sOpeningBracket, N_CHARS(sOpeningBracket));
 
         writeId(Element);
         writeFastAttributeList(Attribs);
 
-        writeBytes(toUnoSequence(maClosingBracket));
+        writeBytes(sClosingBracket, N_CHARS(sClosingBracket));
     }
 
     void SAL_CALL FastSaxSerializer::endFastElement( ::sal_Int32 Element )
@@ -171,11 +173,11 @@ namespace sax_fastparser {
         m_DebugStartedElements.pop();
 #endif
 
-        writeBytes(toUnoSequence(maOpeningBracketAndSlash));
+        writeBytes(sOpeningBracketAndSlash, N_CHARS(sOpeningBracketAndSlash));
 
         writeId(Element);
 
-        writeBytes(toUnoSequence(maClosingBracket));
+        writeBytes(sClosingBracket, N_CHARS(sClosingBracket));
     }
 
     void SAL_CALL FastSaxSerializer::singleFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs )
@@ -184,12 +186,12 @@ namespace sax_fastparser {
         if ( !maMarkStack.empty() )
             maMarkStack.top()->setCurrentElement( Element );
 
-        writeBytes(toUnoSequence(maOpeningBracket));
+        writeBytes(sOpeningBracket, N_CHARS(sOpeningBracket));
 
         writeId(Element);
         writeFastAttributeList(Attribs);
 
-        writeBytes(toUnoSequence(maSlashAndClosingBracket));
+        writeBytes(sSlashAndClosingBracket, N_CHARS(sSlashAndClosingBracket));
     }
 
     void SAL_CALL FastSaxSerializer::setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream )
@@ -213,7 +215,7 @@ namespace sax_fastparser {
         sal_Int32 nAttrLength = aAttrSeq.getLength();
         for (sal_Int32 i = 0; i < nAttrLength; i++)
         {
-            writeBytes(toUnoSequence(maSpace));
+            writeBytes(sSpace, N_CHARS(sSpace));
 
             OUString const& rAttrName(pAttr[i].Name);
 #ifdef DBG_UTIL
@@ -222,9 +224,9 @@ namespace sax_fastparser {
             DebugAttributes.insert(rAttrName);
 #endif
             write(rAttrName);
-            writeBytes(toUnoSequence(maEqualSignAndQuote));
+            writeBytes(sEqualSignAndQuote, N_CHARS(sEqualSignAndQuote));
             write(pAttr[i].Value, true);
-            writeBytes(toUnoSequence(maQuote));
+            writeBytes(sQuote, N_CHARS(sQuote));
         }
 
         Sequence< FastAttribute > aFastAttrSeq = Attribs->getFastAttributes();
@@ -232,7 +234,7 @@ namespace sax_fastparser {
         sal_Int32 nFastAttrLength = aFastAttrSeq.getLength();
         for (sal_Int32 j = 0; j < nFastAttrLength; j++)
         {
-            writeBytes(toUnoSequence(maSpace));
+            writeBytes(sSpace, N_CHARS(sSpace));
 
             sal_Int32 nToken = pFastAttr[j].Token;
             writeId(nToken);
@@ -245,11 +247,11 @@ namespace sax_fastparser {
             DebugAttributes.insert(name);
 #endif
 
-            writeBytes(toUnoSequence(maEqualSignAndQuote));
+            writeBytes(sEqualSignAndQuote, N_CHARS(sEqualSignAndQuote));
 
             write(pFastAttr[j].Value, true);
 
-            writeBytes(toUnoSequence(maQuote));
+            writeBytes(sQuote, N_CHARS(sQuote));
         }
     }
 
@@ -292,24 +294,31 @@ namespace sax_fastparser {
         }
     }
 
-    void FastSaxSerializer::writeBytes( const char* pStr, size_t nLen )
+    void FastSaxSerializer::writeBytes( const Sequence< sal_Int8 >& rData )
         throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     {
-        writeBytes( Sequence< sal_Int8 >(
-            reinterpret_cast<const sal_Int8*>(pStr), nLen) );
+        writeBytes( reinterpret_cast<const char*>(rData.getConstArray()), rData.getLength() );
     }
 
-    void FastSaxSerializer::writeBytes( const Sequence< ::sal_Int8 >& aData ) throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
+    void FastSaxSerializer::writeBytes( const char* pStr, size_t nLen )
+        throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     {
         if ( maMarkStack.empty() )
-            writeOutput( aData );
+            writeOutput( reinterpret_cast<const sal_Int8*>(pStr), nLen );
         else
-            maMarkStack.top()->append( aData );
+            maMarkStack.top()->append( Sequence< sal_Int8 >(
+                reinterpret_cast<const sal_Int8*>(pStr), nLen) );
     }
 
     void FastSaxSerializer::writeOutput( const Sequence< ::sal_Int8 >& aData ) throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     {
-        maOutputStream.writeBytes( aData );
+        writeOutput( aData.getConstArray(), aData.getLength() );
+    }
+
+    void FastSaxSerializer::writeOutput( const sal_Int8* pStr, size_t nLen )
+        throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
+    {
+        maOutputStream.writeBytes( pStr, nLen );
         // Write when the sequence gets big enough
         if (maOutputStream.getSize() > 0x10000)
         {
diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx
index bf27abc..b84c1cc 100644
--- a/sax/source/tools/fastserializer.hxx
+++ b/sax/source/tools/fastserializer.hxx
@@ -213,19 +213,12 @@ private:
 #endif
 
     void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
+    /// Write to maOutputData and if it's big enough flush that to mxOutputStream
+    void writeOutput( const sal_Int8* pStr, size_t nLen )
+        throw (css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException);
     void writeOutput( const css::uno::Sequence< ::sal_Int8 >& aData )
         throw (css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException);
 
-protected:
-    rtl::ByteSequence maClosingBracket;
-    rtl::ByteSequence maSlashAndClosingBracket;
-    rtl::ByteSequence maColon;
-    rtl::ByteSequence maOpeningBracket;
-    rtl::ByteSequence maOpeningBracketAndSlash;
-    rtl::ByteSequence maQuote;
-    rtl::ByteSequence maEqualSignAndQuote;
-    rtl::ByteSequence maSpace;
-
     /** Forward the call to the output stream, or write to the stack.
 
         The latter in the case that we are inside a mark().
commit 8dc668999a9fea8c6fe8acb84dbe1588f670fd78
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Fri Sep 26 15:08:17 2014 +0200

    FastSerializer: Remove escapeXml() creating OUString(Buffer)
    
    Instead directly write the content.
    
    Change-Id: I7b6db925348b879a013acbd2a76a80d590f721c0

diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index 56b27af..300c0d3 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -76,39 +76,36 @@ namespace sax_fastparser {
         writeBytes(toUnoSequence(aXmlHeader));
     }
 
-    OUString FastSaxSerializer::escapeXml( const OUString& s )
+    void FastSaxSerializer::write( const OUString& sOutput, bool bEscape )
     {
-        OUStringBuffer sBuf( s.getLength() );
-        const sal_Unicode* pStr = s.getStr();
-        sal_Int32 nLen = s.getLength();
-        for( sal_Int32 i = 0; i < nLen; ++i)
+        write( OUStringToOString(sOutput, RTL_TEXTENCODING_UTF8), bEscape );
+    }
+
+    void FastSaxSerializer::write( const OString& sOutput, bool bEscape )
+    {
+        if (!bEscape)
         {
-            sal_Unicode c = pStr[ i ];
+            writeBytes( sOutput.getStr(), sOutput.getLength() );
+            return;
+        }
+
+        const char* pStr = sOutput.getStr();
+        sal_Int32 nLen = sOutput.getLength();
+        for (sal_Int32 i = 0; i < nLen; ++i)
+        {
+            char 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;
-                case '\n':  sBuf.appendAscii( "
" );    break;
-                case '\r':  sBuf.appendAscii( "
" );    break;
-                default:    sBuf.append( c );               break;
+                case '<':   writeBytes( "<", 4 );     break;
+                case '>':   writeBytes( ">", 4 );     break;
+                case '&':   writeBytes( "&", 5 );    break;
+                case '\'':  writeBytes( "'", 6 );   break;
+                case '"':   writeBytes( """, 6 );   break;
+                case '\n':  writeBytes( "
", 5 );    break;
+                case '\r':  writeBytes( "
", 5 );    break;
+                default:    writeBytes( &c, 1 );          break;
             }
         }
-        return sBuf.makeStringAndClear();
-    }
-
-    void FastSaxSerializer::write( const OUString& sOutput )
-    {
-        write( OUStringToOString(sOutput, RTL_TEXTENCODING_UTF8) );
-    }
-
-    void FastSaxSerializer::write( const OString& sOutput )
-    {
-        writeBytes( Sequence< sal_Int8 >(
-                    reinterpret_cast< const sal_Int8*>( sOutput.getStr() ),
-                    sOutput.getLength() ) );
     }
 
     void SAL_CALL FastSaxSerializer::endDocument(  ) throw (SAXException, RuntimeException)
@@ -226,7 +223,7 @@ namespace sax_fastparser {
 #endif
             write(rAttrName);
             writeBytes(toUnoSequence(maEqualSignAndQuote));
-            write(escapeXml(pAttr[i].Value));
+            write(pAttr[i].Value, true);
             writeBytes(toUnoSequence(maQuote));
         }
 
@@ -250,7 +247,7 @@ namespace sax_fastparser {
 
             writeBytes(toUnoSequence(maEqualSignAndQuote));
 
-            write(escapeXml(pFastAttr[j].Value));
+            write(pFastAttr[j].Value, true);
 
             writeBytes(toUnoSequence(maQuote));
         }
@@ -295,6 +292,13 @@ namespace sax_fastparser {
         }
     }
 
+    void FastSaxSerializer::writeBytes( const char* pStr, size_t nLen )
+        throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
+    {
+        writeBytes( Sequence< sal_Int8 >(
+            reinterpret_cast<const sal_Int8*>(pStr), nLen) );
+    }
+
     void FastSaxSerializer::writeBytes( const Sequence< ::sal_Int8 >& aData ) throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     {
         if ( maMarkStack.empty() )
diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx
index d754b98..bf27abc 100644
--- a/sax/source/tools/fastserializer.hxx
+++ b/sax/source/tools/fastserializer.hxx
@@ -110,10 +110,8 @@ public:
     void SAL_CALL writeId( ::sal_Int32 Element );
     OString SAL_CALL getId( ::sal_Int32 Element );
 
-    void write( const OUString& s );
-    void write( const OString& s );
-
-    static OUString escapeXml( const OUString& s );
+    void write( const OUString& s, bool bEscape = false );
+    void write( const OString& s, bool bEscape = false );
 
 public:
     /** From now on, don't write directly to the stream, but to top of a stack.
@@ -233,6 +231,7 @@ protected:
         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);
+    void writeBytes( const char* pStr, size_t nLen ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
 };
 
 } // namespace sax_fastparser
diff --git a/sax/source/tools/fshelper.cxx b/sax/source/tools/fshelper.cxx
index cb2c7f7..0e5df28 100644
--- a/sax/source/tools/fshelper.cxx
+++ b/sax/source/tools/fshelper.cxx
@@ -139,12 +139,14 @@ FastSerializerHelper* FastSerializerHelper::write(double value)
 
 FastSerializerHelper* FastSerializerHelper::writeEscaped(const char* value)
 {
-    return writeEscaped(OUString::createFromAscii(value));
+    mpSerializer->write(OString(value), true);
+    return this;
 }
 
 FastSerializerHelper* FastSerializerHelper::writeEscaped(const OUString& value)
 {
-    return write(FastSaxSerializer::escapeXml(value));
+    mpSerializer->write(value, true);
+    return this;
 }
 
 FastSerializerHelper* FastSerializerHelper::writeId(sal_Int32 tokenId)
commit 6be21256bdca3d1d1e32b0abec53ba9695ea5808
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Thu Sep 25 17:06:22 2014 +0200

    FastSerializer: Have OString version of write() too.
    
    And remove characters() member function.
    
    Change-Id: Ifcedbb6d969b7b057ff378d2fbce09c2dde5ac18

diff --git a/include/sax/fshelper.hxx b/include/sax/fshelper.hxx
index 8a9f1cc..d83ce78 100644
--- a/include/sax/fshelper.hxx
+++ b/include/sax/fshelper.hxx
@@ -126,6 +126,7 @@ public:
 
     FastSerializerHelper* write(const char* value);
     FastSerializerHelper* write(const OUString& value);
+    FastSerializerHelper* write(const OString& value);
     FastSerializerHelper* write(sal_Int32 value);
     FastSerializerHelper* write(sal_Int64 value);
     FastSerializerHelper* write(double value);
diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index a6b5afd..56b27af 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -99,9 +99,13 @@ namespace sax_fastparser {
         return sBuf.makeStringAndClear();
     }
 
-    void FastSaxSerializer::write( const OUString& s )
+    void FastSaxSerializer::write( const OUString& sOutput )
+    {
+        write( OUStringToOString(sOutput, RTL_TEXTENCODING_UTF8) );
+    }
+
+    void FastSaxSerializer::write( const OString& sOutput )
     {
-        OString sOutput( OUStringToOString( s, RTL_TEXTENCODING_UTF8 ) );
         writeBytes( Sequence< sal_Int8 >(
                     reinterpret_cast< const sal_Int8*>( sOutput.getStr() ),
                     sOutput.getLength() ) );
@@ -191,12 +195,6 @@ namespace sax_fastparser {
         writeBytes(toUnoSequence(maSlashAndClosingBracket));
     }
 
-    void SAL_CALL FastSaxSerializer::characters( const OUString& aChars )
-        throw (SAXException, RuntimeException)
-    {
-        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)
     {
diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx
index 45535f2..d754b98 100644
--- a/sax/source/tools/fastserializer.hxx
+++ b/sax/source/tools/fastserializer.hxx
@@ -100,10 +100,6 @@ public:
     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);
 
-    /// receives notification of character data.
-    void SAL_CALL characters( const OUString& aChars )
-        throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
-
     void SAL_CALL setOutputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xOutputStream )
         throw (::com::sun::star::uno::RuntimeException);
 
@@ -114,6 +110,9 @@ public:
     void SAL_CALL writeId( ::sal_Int32 Element );
     OString SAL_CALL getId( ::sal_Int32 Element );
 
+    void write( const OUString& s );
+    void write( const OString& s );
+
     static OUString escapeXml( const OUString& s );
 
 public:
@@ -216,7 +215,6 @@ private:
 #endif
 
     void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
-    void write( const OUString& s );
     void writeOutput( const css::uno::Sequence< ::sal_Int8 >& aData )
         throw (css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException);
 
diff --git a/sax/source/tools/fshelper.cxx b/sax/source/tools/fshelper.cxx
index c49c0da..cb2c7f7 100644
--- a/sax/source/tools/fshelper.cxx
+++ b/sax/source/tools/fshelper.cxx
@@ -107,28 +107,34 @@ void FastSerializerHelper::singleElement(sal_Int32 elementTokenId, XFastAttribut
 
 FastSerializerHelper* FastSerializerHelper::write(const char* value)
 {
-    return write(OUString::createFromAscii(value));
+    return write(OString(value));
 }
 
 FastSerializerHelper* FastSerializerHelper::write(const OUString& value)
 {
-    mpSerializer->characters(value);
+    mpSerializer->write(value);
+    return this;
+}
+
+FastSerializerHelper* FastSerializerHelper::write(const OString& value)
+{
+    mpSerializer->write(value);
     return this;
 }
 
 FastSerializerHelper* FastSerializerHelper::write(sal_Int32 value)
 {
-    return write(OUString::number(value));
+    return write(OString::number(value));
 }
 
 FastSerializerHelper* FastSerializerHelper::write(sal_Int64 value)
 {
-    return write(OUString::number(value));
+    return write(OString::number(value));
 }
 
 FastSerializerHelper* FastSerializerHelper::write(double value)
 {
-    return write(OUString::number(value));
+    return write(OString::number(value));
 }
 
 FastSerializerHelper* FastSerializerHelper::writeEscaped(const char* value)
commit d55648b7e5cd499196389ed9ba5c7badbf3522e5
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Thu Sep 25 16:34:36 2014 +0200

    FastSerializer: check for valid output stream in one place is enough
    
    Change-Id: Id89fb1f0444331c2858a9795ae81dcdb875d3d2b

diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index d85bfef..a6b5afd 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -72,9 +72,6 @@ namespace sax_fastparser {
 
     void SAL_CALL FastSaxSerializer::startDocument(  ) throw (SAXException, RuntimeException)
     {
-        assert(mxOutputStream.is()); // cannot do anything without that
-        if (!mxOutputStream.is())
-            return;
         rtl::ByteSequence aXmlHeader((const sal_Int8*) "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n", 56);
         writeBytes(toUnoSequence(aXmlHeader));
     }
@@ -112,9 +109,6 @@ namespace sax_fastparser {
 
     void SAL_CALL FastSaxSerializer::endDocument(  ) throw (SAXException, RuntimeException)
     {
-        if (!mxOutputStream.is())
-            return;
-
         maOutputStream.flush();
         mxOutputStream->writeBytes(maOutputData);
     }
@@ -151,9 +145,6 @@ namespace sax_fastparser {
     void SAL_CALL FastSaxSerializer::startFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs )
         throw (SAXException, RuntimeException)
     {
-        if (!mxOutputStream.is())
-            return;
-
         if ( !maMarkStack.empty() )
             maMarkStack.top()->setCurrentElement( Element );
 
@@ -172,9 +163,6 @@ namespace sax_fastparser {
     void SAL_CALL FastSaxSerializer::endFastElement( ::sal_Int32 Element )
         throw (SAXException, RuntimeException)
     {
-        if (!mxOutputStream.is())
-            return;
-
 #ifdef DBG_UTIL
         assert(!m_DebugStartedElements.empty());
         // Well-formedness constraint: Element Type Match
@@ -192,9 +180,6 @@ namespace sax_fastparser {
     void SAL_CALL FastSaxSerializer::singleFastElement( ::sal_Int32 Element, const Reference< XFastAttributeList >& Attribs )
         throw (SAXException, RuntimeException)
     {
-        if (!mxOutputStream.is())
-            return;
-
         if ( !maMarkStack.empty() )
             maMarkStack.top()->setCurrentElement( Element );
 
@@ -209,9 +194,6 @@ namespace sax_fastparser {
     void SAL_CALL FastSaxSerializer::characters( const OUString& aChars )
         throw (SAXException, RuntimeException)
     {
-        if (!mxOutputStream.is())
-            return;
-
         write( aChars );
     }
 
@@ -219,7 +201,6 @@ namespace sax_fastparser {
         throw (::com::sun::star::uno::RuntimeException)
     {
         mxOutputStream = xOutputStream;
-        assert(mxOutputStream.is()); // cannot do anything without that
     }
 
     void SAL_CALL FastSaxSerializer::setFastTokenHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >& xFastTokenHandler )
diff --git a/sax/source/tools/fshelper.cxx b/sax/source/tools/fshelper.cxx
index c19bd4b..c49c0da 100644
--- a/sax/source/tools/fshelper.cxx
+++ b/sax/source/tools/fshelper.cxx
@@ -35,6 +35,7 @@ FastSerializerHelper::FastSerializerHelper(const Reference< io::XOutputStream >&
     mxTokenHandler = css::xml::sax::FastTokenHandler::create(xContext);
 
     mpSerializer->setFastTokenHandler( mxTokenHandler );
+    assert(xOutputStream.is()); // cannot do anything without that
     mpSerializer->setOutputStream( xOutputStream );
     if( bWriteHeader )
         mpSerializer->startDocument();
commit cc3ac382a2827a42d45f3fcb5e2149c163667ba0
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Thu Sep 25 14:45:55 2014 +0200

    FastSerializer: Do not keep whole sequence in memory; write in chunks
    
    Change-Id: Ibca65a2b8397358ac4013c8e5b53389ac6949e4d

diff --git a/comphelper/source/streaming/seqstream.cxx b/comphelper/source/streaming/seqstream.cxx
index d66ce3b..aec4519 100644
--- a/comphelper/source/streaming/seqstream.cxx
+++ b/comphelper/source/streaming/seqstream.cxx
@@ -214,6 +214,8 @@ void SAL_CALL OSequenceOutputStream::flush(  ) throw(NotConnectedException, Buff
 
     // cut the sequence to the real size
     m_rSequence.realloc(m_nSize);
+    // and next time write to the beginning
+    m_nSize = 0;
 }
 
 
diff --git a/include/comphelper/seqstream.hxx b/include/comphelper/seqstream.hxx
index 13dd4dc..75b1934 100644
--- a/include/comphelper/seqstream.hxx
+++ b/include/comphelper/seqstream.hxx
@@ -115,13 +115,16 @@ public:
 
     virtual ~OSequenceOutputStream() { if (m_bConnected) closeOutput(); }
 
+    sal_Int32 getSize() const { return m_nSize; }
+
     /// same as XOutputStream::writeBytes (as expected :)
     virtual void SAL_CALL 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, std::exception) SAL_OVERRIDE;
-    /// this is a dummy in this implementation, no buffering is used
+    /** Resizes the sequence used for writing to the really used size.
+     *  Next time, writeBytes will write to the beginning of the sequence.
+    */
     virtual void SAL_CALL flush(  ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
-    /** closes the output stream. In the case of this class, this means that the sequence used for writing is
-        resized to the really used size and not used any further, every subsequent call to one of the XOutputStream
-        methods will throw a <code>NotConnectedException</code>.
+    /** Calls flush() and closes the output stream to prevent further manipulation with the sequence.
+        Every subsequent call to one of the XOutputStream methods will throw a <code>NotConnectedException</code>.
     */
     virtual void SAL_CALL closeOutput(  ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
 };
diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index dfa37c7..d85bfef 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -53,8 +53,8 @@ using ::com::sun::star::io::BufferSizeExceededException;
 
 namespace sax_fastparser {
     FastSaxSerializer::FastSaxSerializer( )
-        : maOutputData()
-        , maOutputStream(maOutputData)
+        : maOutputData(0x4000)
+        , maOutputStream(maOutputData, 1.3, 0x1000, 0x4000)
         , mxOutputStream()
         , mxFastTokenHandler()
         , maMarkStack()
@@ -298,7 +298,7 @@ namespace sax_fastparser {
 
         if ( maMarkStack.size() == 1  && eMergeType != MERGE_MARKS_IGNORE)
         {
-            maOutputStream.writeBytes( maMarkStack.top()->getData() );
+            writeOutput( maMarkStack.top()->getData() );
             maMarkStack.pop();
             return;
         }
@@ -319,11 +319,22 @@ namespace sax_fastparser {
     void FastSaxSerializer::writeBytes( const Sequence< ::sal_Int8 >& aData ) throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     {
         if ( maMarkStack.empty() )
-            maOutputStream.writeBytes( aData );
+            writeOutput( aData );
         else
             maMarkStack.top()->append( aData );
     }
 
+    void FastSaxSerializer::writeOutput( const Sequence< ::sal_Int8 >& aData ) throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
+    {
+        maOutputStream.writeBytes( aData );
+        // Write when the sequence gets big enough
+        if (maOutputStream.getSize() > 0x10000)
+        {
+            maOutputStream.flush();
+            mxOutputStream->writeBytes(maOutputData);
+        }
+    }
+
     FastSaxSerializer::Int8Sequence& FastSaxSerializer::ForMerge::getData()
     {
         merge( maData, maPostponed, true );
diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx
index 147d767..45535f2 100644
--- a/sax/source/tools/fastserializer.hxx
+++ b/sax/source/tools/fastserializer.hxx
@@ -217,6 +217,8 @@ private:
 
     void writeFastAttributeList( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs );
     void write( const OUString& s );
+    void writeOutput( const css::uno::Sequence< ::sal_Int8 >& aData )
+        throw (css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException);
 
 protected:
     rtl::ByteSequence maClosingBracket;
commit 8cc5b621aa308de2272bed32bc8cd88626455831
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Thu Sep 25 11:39:11 2014 +0200

    Remove mutex from OSequenceOutputStream; it's intended to be fast
    
    Make the caller responsible for using it wisely.
    AFAICS it's used only in FastSaxSerializer, so far.
    
    Change-Id: I50d48fd7f3e6cdeb9e4637868da213b8171e542b

diff --git a/comphelper/source/streaming/seqstream.cxx b/comphelper/source/streaming/seqstream.cxx
index 5bc44a5..d66ce3b 100644
--- a/comphelper/source/streaming/seqstream.cxx
+++ b/comphelper/source/streaming/seqstream.cxx
@@ -159,7 +159,6 @@ OSequenceOutputStream::OSequenceOutputStream(Sequence< sal_Int8 >& _rSeq, double
 
 void SAL_CALL OSequenceOutputStream::writeBytes( const Sequence< sal_Int8 >& _rData ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception)
 {
-    MutexGuard aGuard(m_aMutex);
     if (!m_bConnected)
         throw NotConnectedException();
 
@@ -210,7 +209,6 @@ void SAL_CALL OSequenceOutputStream::writeBytes( const Sequence< sal_Int8 >& _rD
 
 void SAL_CALL OSequenceOutputStream::flush(  ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception)
 {
-    MutexGuard aGuard(m_aMutex);
     if (!m_bConnected)
         throw NotConnectedException();
 
@@ -221,12 +219,7 @@ void SAL_CALL OSequenceOutputStream::flush(  ) throw(NotConnectedException, Buff
 
 void SAL_CALL OSequenceOutputStream::closeOutput(  ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException, std::exception)
 {
-    MutexGuard aGuard(m_aMutex);
-    if (!m_bConnected)
-        throw NotConnectedException();
-
-    // cut the sequence to the real size
-    m_rSequence.realloc(m_nSize);
+    flush();
     // and don't allow any further accesses
     m_bConnected = false;
 }
diff --git a/include/comphelper/seqstream.hxx b/include/comphelper/seqstream.hxx
index d4f301c..13dd4dc 100644
--- a/include/comphelper/seqstream.hxx
+++ b/include/comphelper/seqstream.hxx
@@ -89,7 +89,6 @@ protected:
     sal_Int32                                       m_nSize;
 
     bool                                            m_bConnected; ///< closeOutput has been called ?
-    ::osl::Mutex                                    m_aMutex;
 
 public:
     /** constructs the object. Everything written into the stream through the XOutputStream methods will be forwarded
commit c8b3ed2ec3bec708df678d54fd68a1a78c6f7c8a
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Thu Sep 25 11:07:21 2014 +0200

    FastSerializer: We already know the attribute value
    
    Change-Id: I6996e15f99b94b50c1903092d7424a96339ccfaf

diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index a9520e4..dfa37c7 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -271,7 +271,7 @@ namespace sax_fastparser {
 
             writeBytes(toUnoSequence(maEqualSignAndQuote));
 
-            write(escapeXml(Attribs->getValue(pFastAttr[j].Token)));
+            write(escapeXml(pFastAttr[j].Value));
 
             writeBytes(toUnoSequence(maQuote));
         }
commit b7266ddb2f580a2ed3c558d1996b5e2760023145
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Wed Sep 24 14:55:02 2014 +0200

    FastSerializer: Buffer output and write it only at the end
    
    Use OSequenceOutputStream class to concatenate strings in a
    Sequence<sal_Int8> buffer. And write data to file only at the end.
    
    The design is a bit fragile, since all FSHelpers need to be destroyed
    before calling FilterBase::commitStorage(). Otherwise data is not written.
    
    Change-Id: I26b02335ef36011bfcda17484b560811d18c7657

diff --git a/include/comphelper/seqstream.hxx b/include/comphelper/seqstream.hxx
index d572995..d4f301c 100644
--- a/include/comphelper/seqstream.hxx
+++ b/include/comphelper/seqstream.hxx
@@ -74,27 +74,23 @@ public:
 private:
     inline sal_Int32 avail();
 };
-typedef ::cppu::WeakImplHelper1< ::com::sun::star::io::XOutputStream > OSequenceOutputStream_Base;
 
-class OSequenceOutputStream : public OSequenceOutputStream_Base
+class COMPHELPER_DLLPUBLIC OSequenceOutputStream :
+    public ::cppu::WeakImplHelper1< ::com::sun::star::io::XOutputStream >
 {
 protected:
     ::com::sun::star::uno::Sequence< sal_Int8 >&    m_rSequence;
     double                                          m_nResizeFactor;
     sal_Int32                                       m_nMinimumResize;
     sal_Int32                                       m_nMaximumResize;
+    /** the size of the virtual stream. This is not the size of the sequence,
+        but the number of bytes written into the stream at a given moment.
+     */
     sal_Int32                                       m_nSize;
-        // the size of the virtual stream. This is not the size of the sequence, but the number of bytes written
-        // into the stream at a given moment.
-
-    bool                                        m_bConnected;
-        // closeOutput has been called ?
 
+    bool                                            m_bConnected; ///< closeOutput has been called ?
     ::osl::Mutex                                    m_aMutex;
 
-protected:
-    virtual ~OSequenceOutputStream() { if (m_bConnected) closeOutput(); }
-
 public:
     /** constructs the object. Everything written into the stream through the XOutputStream methods will be forwarded
         to the sequence, reallocating it if necessary. Writing will start at offset 0 within the sequence.
@@ -118,6 +114,8 @@ public:
         sal_Int32 _nMaximumResize = -1
         );
 
+    virtual ~OSequenceOutputStream() { if (m_bConnected) closeOutput(); }
+
     /// same as XOutputStream::writeBytes (as expected :)
     virtual void SAL_CALL 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, std::exception) SAL_OVERRIDE;
     /// this is a dummy in this implementation, no buffering is used
diff --git a/sax/source/tools/fastserializer.cxx b/sax/source/tools/fastserializer.cxx
index fbce18a..a9520e4 100644
--- a/sax/source/tools/fastserializer.cxx
+++ b/sax/source/tools/fastserializer.cxx
@@ -53,7 +53,9 @@ using ::com::sun::star::io::BufferSizeExceededException;
 
 namespace sax_fastparser {
     FastSaxSerializer::FastSaxSerializer( )
-        : mxOutputStream()
+        : maOutputData()
+        , maOutputStream(maOutputData)
+        , mxOutputStream()
         , mxFastTokenHandler()
         , maMarkStack()
         , maClosingBracket((const sal_Int8 *)">", 1)
@@ -112,6 +114,9 @@ namespace sax_fastparser {
     {
         if (!mxOutputStream.is())
             return;
+
+        maOutputStream.flush();
+        mxOutputStream->writeBytes(maOutputData);
     }
 
     void SAL_CALL FastSaxSerializer::writeId( ::sal_Int32 nElement )
@@ -293,7 +298,7 @@ namespace sax_fastparser {
 
         if ( maMarkStack.size() == 1  && eMergeType != MERGE_MARKS_IGNORE)
         {
-            mxOutputStream->writeBytes( maMarkStack.top()->getData() );
+            maOutputStream.writeBytes( maMarkStack.top()->getData() );
             maMarkStack.pop();
             return;
         }
@@ -314,7 +319,7 @@ namespace sax_fastparser {
     void FastSaxSerializer::writeBytes( const Sequence< ::sal_Int8 >& aData ) throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException )
     {
         if ( maMarkStack.empty() )
-            mxOutputStream->writeBytes( aData );
+            maOutputStream.writeBytes( aData );
         else
             maMarkStack.top()->append( aData );
     }
diff --git a/sax/source/tools/fastserializer.hxx b/sax/source/tools/fastserializer.hxx
index a88e3ca..147d767 100644
--- a/sax/source/tools/fastserializer.hxx
+++ b/sax/source/tools/fastserializer.hxx
@@ -29,6 +29,7 @@
 
 #include <boost/shared_ptr.hpp>
 
+#include <comphelper/seqstream.hxx>
 #include "sax/fshelper.hxx"
 
 namespace sax_fastparser {
@@ -148,6 +149,11 @@ public:
     void mergeTopMarks( sax_fastparser::MergeMarksEnum eMergeType = sax_fastparser::MERGE_MARKS_APPEND );
 
 private:
+    /// Buffer written to mxOutputStream at the end, called from FSHelper destructor.
+    css::uno::Sequence< sal_Int8 > maOutputData;
+    /// Helper class to dynamically allocate memory when needed for maOutputData.
+    comphelper::OSequenceOutputStream maOutputStream;
+    /// Output stream, usually writing data into files.
     ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > mxOutputStream;
     ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler > mxFastTokenHandler;
 
diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx
index e84b474..0297da6 100644
--- a/sc/source/filter/excel/excdoc.cxx
+++ b/sc/source/filter/excel/excdoc.cxx
@@ -879,8 +879,6 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
 
     rWorkbook->endElement( XML_workbook );
     rWorkbook.reset();
-
-    rStrm.commitStorage();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
index 6f36440..31e39c7 100644
--- a/sc/source/filter/excel/xestream.cxx
+++ b/sc/source/filter/excel/xestream.cxx
@@ -939,6 +939,7 @@ XclExpXmlStream::XclExpXmlStream( const Reference< XComponentContext >& rCC )
 
 XclExpXmlStream::~XclExpXmlStream()
 {
+    assert(maStreams.empty() && "Forgotten PopStream()?");
 }
 
 sax_fastparser::FSHelperPtr& XclExpXmlStream::GetCurrentStream()
@@ -1103,6 +1104,12 @@ bool XclExpXmlStream::exportDocument()
         aDocRoot.WriteXml( *this );
     }
 
+    PopStream();
+    // Free all FSHelperPtr, to flush data before commiting storage
+    maOpenedStreamMap.clear();
+
+    commitStorage();
+
     if (xStatusIndicator.is())
         xStatusIndicator->end();
     mpRoot = NULL;
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx
index caf46c6..9fb836b 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -384,6 +384,8 @@ bool PowerPointExport::exportDocument() throw (css::uno::RuntimeException, std::
 
     mPresentationFS->endElementNS( XML_p, XML_presentation );
     mPresentationFS.reset();
+    // Free all FSHelperPtr, to flush data before commiting storage
+    mpSlidesFSArray.clear();
 
     commitStorage();
 


More information about the Libreoffice-commits mailing list