From f92183833fa569006602ac7e93c906d2094e0d4d Mon Sep 17 00:00:00 2001 From: Matúš Kukan Date: Sun, 14 Dec 2014 00:11:53 +0100 Subject: package: Better to use temporary files for huge memory zip streams ZipPackageBuffer was holding the whole compressed data stream in one uno::Sequence which seems to be a lot for big documents in some cases. Change-Id: Ib10d00ac54df9674231f4bbf047fab7e9b0a7d45 --- package/inc/ZipOutputEntry.hxx | 5 +++-- package/source/zipapi/ZipOutputEntry.cxx | 13 ++++++++----- package/source/zipapi/ZipOutputStream.cxx | 16 +++++++++++++++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/package/inc/ZipOutputEntry.hxx b/package/inc/ZipOutputEntry.hxx index 1cf499f5efb3..48e33ebb546f 100644 --- a/package/inc/ZipOutputEntry.hxx +++ b/package/inc/ZipOutputEntry.hxx @@ -20,6 +20,7 @@ #define INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX #include +#include #include #include #include @@ -36,7 +37,7 @@ class ZipOutputEntry { ::com::sun::star::uno::Sequence< sal_Int8 > m_aDeflateBuffer; ZipUtils::Deflater m_aDeflater; - css::uno::Reference< ZipPackageBuffer > m_pBuffer; + css::uno::Reference< css::io::XTempFile > m_xTempFile; css::uno::Reference< css::io::XOutputStream > m_xOutStream; ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XCipherContext > m_xCipherContext; @@ -56,7 +57,7 @@ public: ~ZipOutputEntry(); - css::uno::Sequence< sal_Int8 > getData(); + css::uno::Reference< css::io::XInputStream > getData(); ZipEntry* getZipEntry() { return m_pCurrentEntry; } ZipPackageStream* getZipPackageStream() { return m_pCurrentStream; } bool isEncrypt() { return m_bEncryptCurrentEntry; } diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx index abffb1d6aede..8243bdcdf76a 100644 --- a/package/source/zipapi/ZipOutputEntry.cxx +++ b/package/source/zipapi/ZipOutputEntry.cxx @@ -19,6 +19,7 @@ #include +#include #include #include @@ -57,8 +58,8 @@ ZipOutputEntry::ZipOutputEntry( } else { - m_pBuffer = new ZipPackageBuffer(n_ConstBufferSize); - m_xOutStream = m_pBuffer; + m_xTempFile = io::TempFile::create(rxContext); + m_xOutStream = m_xTempFile->getOutputStream(); } assert(m_pCurrentEntry->nMethod == DEFLATED && "Use ZipPackageStream::rawWrite() for STORED entries"); if (m_bEncryptCurrentEntry) @@ -72,10 +73,12 @@ ZipOutputEntry::~ZipOutputEntry( void ) { } -uno::Sequence< sal_Int8 > ZipOutputEntry::getData() +uno::Reference< io::XInputStream > ZipOutputEntry::getData() { - m_pBuffer->realloc(m_pBuffer->getPosition()); - return m_pBuffer->getSequence(); + m_xOutStream->closeOutput(); + uno::Reference< io::XSeekable > xTempSeek(m_xOutStream, UNO_QUERY_THROW); + xTempSeek->seek(0); + return m_xTempFile->getInputStream(); } void ZipOutputEntry::closeEntry() diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx index 058cb3d2224d..5c49b1bfc6b7 100644 --- a/package/source/zipapi/ZipOutputStream.cxx +++ b/package/source/zipapi/ZipOutputStream.cxx @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -101,7 +102,20 @@ void ZipOutputStream::finish() for (size_t i = 0; i < m_aEntries.size(); i++) { writeLOC(m_aEntries[i]->getZipEntry(), m_aEntries[i]->isEncrypt()); - rawWrite(m_aEntries[i]->getData()); + + sal_Int32 nRead; + uno::Sequence< sal_Int8 > aSequence(n_ConstBufferSize); + uno::Reference< io::XInputStream > xInput = m_aEntries[i]->getData(); + do + { + nRead = xInput->readBytes(aSequence, n_ConstBufferSize); + if (nRead < n_ConstBufferSize) + aSequence.realloc(nRead); + + rawWrite(aSequence); + } + while (nRead == n_ConstBufferSize); + rawCloseEntry(m_aEntries[i]->isEncrypt()); m_aEntries[i]->getZipPackageStream()->successfullyWritten(m_aEntries[i]->getZipEntry()); -- cgit v1.2.3