Kaydet (Commit) b7266ddb authored tarafından Matúš Kukan's avatar Matúš Kukan

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
üst 5c8ea6d9
......@@ -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
......
......@@ -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 );
}
......
......@@ -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;
......
......@@ -879,8 +879,6 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
rWorkbook->endElement( XML_workbook );
rWorkbook.reset();
rStrm.commitStorage();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -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;
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment