[Libreoffice-commits] core.git: 2 commits - package/inc package/source

Matúš Kukan matus.kukan at collabora.com
Sat Dec 13 15:35:21 PST 2014


 package/inc/ZipOutputEntry.hxx                 |    8 ++++-
 package/inc/ZipOutputStream.hxx                |    1 
 package/source/zipapi/ZipOutputEntry.cxx       |   35 +++++++++++++++++--------
 package/source/zipapi/ZipOutputStream.cxx      |   21 ++++++++++++++-
 package/source/zippackage/ZipPackage.cxx       |    6 +---
 package/source/zippackage/ZipPackageStream.cxx |    7 ++---
 6 files changed, 57 insertions(+), 21 deletions(-)

New commits:
commit f92183833fa569006602ac7e93c906d2094e0d4d
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Sun Dec 14 00:11:53 2014 +0100

    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

diff --git a/package/inc/ZipOutputEntry.hxx b/package/inc/ZipOutputEntry.hxx
index 1cf499f..48e33eb 100644
--- a/package/inc/ZipOutputEntry.hxx
+++ b/package/inc/ZipOutputEntry.hxx
@@ -20,6 +20,7 @@
 #define INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX
 
 #include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XTempFile.hpp>
 #include <com/sun/star/uno/Reference.hxx>
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <com/sun/star/xml/crypto/XCipherContext.hpp>
@@ -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 abffb1d..8243bdc 100644
--- a/package/source/zipapi/ZipOutputEntry.cxx
+++ b/package/source/zipapi/ZipOutputEntry.cxx
@@ -19,6 +19,7 @@
 
 #include <ZipOutputEntry.hxx>
 
+#include <com/sun/star/io/TempFile.hpp>
 #include <com/sun/star/packages/zip/ZipConstants.hpp>
 #include <comphelper/storagehelper.hxx>
 
@@ -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 058cb3d..5c49b1b 100644
--- a/package/source/zipapi/ZipOutputStream.cxx
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -20,6 +20,7 @@
 #include <ZipOutputStream.hxx>
 
 #include <com/sun/star/packages/zip/ZipConstants.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
 #include <com/sun/star/io/XOutputStream.hpp>
 #include <comphelper/storagehelper.hxx>
 #include <osl/diagnose.h>
@@ -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());
commit 43eca2d9f8d87363b5f4bf8c5df92bf06be08c08
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Sat Dec 13 23:09:10 2014 +0100

    package: Create memory buffer only when we need it - if we use parallelism
    
    Otherwise write directly to the resulting zip file.
    
    Change-Id: I75097969f0cccf0b45da591c71221e5ae18668cb

diff --git a/package/inc/ZipOutputEntry.hxx b/package/inc/ZipOutputEntry.hxx
index 26ebb15..1cf499f 100644
--- a/package/inc/ZipOutputEntry.hxx
+++ b/package/inc/ZipOutputEntry.hxx
@@ -19,6 +19,7 @@
 #ifndef INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX
 #define INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX
 
+#include <com/sun/star/io/XOutputStream.hpp>
 #include <com/sun/star/uno/Reference.hxx>
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <com/sun/star/xml/crypto/XCipherContext.hpp>
@@ -36,6 +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::XOutputStream > m_xOutStream;
 
     ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XCipherContext > m_xCipherContext;
     ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XDigestContext > m_xDigestContext;
@@ -48,6 +50,7 @@ class ZipOutputEntry
 
 public:
     ZipOutputEntry(
+        const css::uno::Reference< css::io::XOutputStream >& rxOutStream,
         const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
         ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt = false);
 
diff --git a/package/inc/ZipOutputStream.hxx b/package/inc/ZipOutputStream.hxx
index acf6dc4..d6d7853 100644
--- a/package/inc/ZipOutputStream.hxx
+++ b/package/inc/ZipOutputStream.hxx
@@ -57,6 +57,7 @@ public:
 
     void finish()
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+    css::uno::Reference< css::io::XOutputStream > getStream();
 
     static sal_uInt32 getCurrentDosTime();
     static void setEntry( ZipEntry *pEntry );
diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx
index adbbf25..abffb1d 100644
--- a/package/source/zipapi/ZipOutputEntry.cxx
+++ b/package/source/zipapi/ZipOutputEntry.cxx
@@ -38,18 +38,28 @@ using namespace com::sun::star::packages::zip::ZipConstants;
 
 /** This class is used to deflate Zip entries
  */
-ZipOutputEntry::ZipOutputEntry( const uno::Reference< uno::XComponentContext >& rxContext,
-                        ZipEntry& rEntry,
-                        ZipPackageStream* pStream,
-                        bool bEncrypt)
+ZipOutputEntry::ZipOutputEntry(
+        const css::uno::Reference< css::io::XOutputStream >& rxOutput,
+        const uno::Reference< uno::XComponentContext >& rxContext,
+        ZipEntry& rEntry,
+        ZipPackageStream* pStream,
+        bool bEncrypt)
 : m_aDeflateBuffer(n_ConstBufferSize)
 , m_aDeflater(DEFAULT_COMPRESSION, true)
-, m_pBuffer(new ZipPackageBuffer(n_ConstBufferSize))
 , m_pCurrentEntry(&rEntry)
 , m_nDigested(0)
 , m_bEncryptCurrentEntry(bEncrypt)
 , m_pCurrentStream(pStream)
 {
+    if (rxOutput.is())
+    {
+        m_xOutStream = rxOutput;
+    }
+    else
+    {
+        m_pBuffer = new ZipPackageBuffer(n_ConstBufferSize);
+        m_xOutStream = m_pBuffer;
+    }
     assert(m_pCurrentEntry->nMethod == DEFLATED && "Use ZipPackageStream::rawWrite() for STORED entries");
     if (m_bEncryptCurrentEntry)
     {
@@ -153,7 +163,7 @@ void ZipOutputEntry::doDeflate()
             // FIXME64: uno::Sequence not 64bit safe.
             uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->convertWithCipherContext( aTmpBuffer );
 
-            m_pBuffer->writeBytes( aEncryptionBuffer );
+            m_xOutStream->writeBytes( aEncryptionBuffer );
 
             // the sizes as well as checksum for encrypted streams is calculated here
             m_pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength();
@@ -162,7 +172,7 @@ void ZipOutputEntry::doDeflate()
         }
         else
         {
-            m_pBuffer->writeBytes ( aTmpBuffer );
+            m_xOutStream->writeBytes ( aTmpBuffer );
         }
     }
 
@@ -172,7 +182,7 @@ void ZipOutputEntry::doDeflate()
         uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->finalizeCipherContextAndDispose();
         if ( aEncryptionBuffer.getLength() )
         {
-            m_pBuffer->writeBytes( aEncryptionBuffer );
+            m_xOutStream->writeBytes( aEncryptionBuffer );
 
             // the sizes as well as checksum for encrypted streams is calculated hier
             m_pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength();
diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx
index f16327e..058cb3d 100644
--- a/package/source/zipapi/ZipOutputStream.cxx
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -119,6 +119,11 @@ void ZipOutputStream::finish()
     m_aZipList.clear();
 }
 
+css::uno::Reference< css::io::XOutputStream > ZipOutputStream::getStream()
+{
+    return m_xStream;
+}
+
 void ZipOutputStream::writeEND(sal_uInt32 nOffset, sal_uInt32 nLength)
     throw(IOException, RuntimeException)
 {
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
index 8da7c1f..5f9c179 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -1043,10 +1043,9 @@ void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< uno::Seq
     // the manifest.xml is never encrypted - so pass an empty reference
     ZipOutputStream::setEntry(pEntry);
     aZipOut.writeLOC(pEntry);
-    ZipOutputEntry aZipEntry(m_xContext, *pEntry, NULL);
+    ZipOutputEntry aZipEntry(aZipOut.getStream(), m_xContext, *pEntry, NULL);
     aZipEntry.write(pBuffer->getSequence());
     aZipEntry.closeEntry();
-    aZipOut.rawWrite(aZipEntry.getData());
     aZipOut.rawCloseEntry();
 }
 
@@ -1097,10 +1096,9 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno:
     // there is no encryption in this format currently
     ZipOutputStream::setEntry(pEntry);
     aZipOut.writeLOC(pEntry);
-    ZipOutputEntry aZipEntry(m_xContext, *pEntry, NULL);
+    ZipOutputEntry aZipEntry(aZipOut.getStream(), m_xContext, *pEntry, NULL);
     aZipEntry.write(pBuffer->getSequence());
     aZipEntry.closeEntry();
-    aZipOut.rawWrite(aZipEntry.getData());
     aZipOut.rawCloseEntry();
 }
 
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index 2c9562b..54d0def 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -815,15 +815,16 @@ bool ZipPackageStream::saveChild(
                 if (bParallelDeflate)
                 {
                     // Start a new thread deflating this zip entry
-                    ZipOutputEntry *pZipEntry = new ZipOutputEntry(m_xContext, *pTempEntry, this, bToBeEncrypted);
+                    ZipOutputEntry *pZipEntry = new ZipOutputEntry(
+                            css::uno::Reference<css::io::XOutputStream>(),
+                            m_xContext, *pTempEntry, this, bToBeEncrypted);
                     rZipOut.addDeflatingThread( pZipEntry, new DeflateThread(pZipEntry, xStream) );
                 }
                 else
                 {
                     rZipOut.writeLOC(pTempEntry, bToBeEncrypted);
-                    ZipOutputEntry aZipEntry(m_xContext, *pTempEntry, this, bToBeEncrypted);
+                    ZipOutputEntry aZipEntry(rZipOut.getStream(), m_xContext, *pTempEntry, this, bToBeEncrypted);
                     deflateZipEntry(&aZipEntry, xStream);
-                    rZipOut.rawWrite(aZipEntry.getData());
                     rZipOut.rawCloseEntry(bToBeEncrypted);
                 }
             }


More information about the Libreoffice-commits mailing list