[Libreoffice-commits] core.git: Branch 'feature/perfwork4' - 9 commits - package/inc package/source

Matúš Kukan matus.kukan at collabora.com
Tue Oct 21 07:31:51 PDT 2014


 package/inc/ZipOutputEntry.hxx                   |   29 --
 package/inc/ZipOutputStream.hxx                  |   23 +
 package/inc/ZipPackageFolder.hxx                 |    1 
 package/inc/ZipPackageStream.hxx                 |    6 
 package/source/zipapi/ZipOutputEntry.cxx         |  307 ++++-------------------
 package/source/zipapi/ZipOutputStream.cxx        |  210 +++++++++++++--
 package/source/zippackage/ContentInfo.hxx        |    2 
 package/source/zippackage/ZipPackage.cxx         |   30 +-
 package/source/zippackage/ZipPackageFolder.cxx   |   36 --
 package/source/zippackage/ZipPackageStream.cxx   |  159 +++++++----
 package/source/zippackage/wrapstreamforshare.cxx |    4 
 11 files changed, 396 insertions(+), 411 deletions(-)

New commits:
commit 91ed64991ccb066797b10f782ac2af9aefdb2bf8
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Tue Oct 21 15:17:13 2014 +0200

    package: Finally implement parallel zip entries deflating
    
    For that:
    1, create ZipPackageStream::successfullyWritten to be called after
    the content is written
    2, Do not take mutex when reading from WrapStreamForShare - threads should
    be using different streams anyway, but there is only one common mutex. :-/
    
    Change-Id: I90303e49206b19454dd4141e24cc8be29c433045

diff --git a/package/inc/ZipOutputEntry.hxx b/package/inc/ZipOutputEntry.hxx
index c24d5a9..9e396ce 100644
--- a/package/inc/ZipOutputEntry.hxx
+++ b/package/inc/ZipOutputEntry.hxx
@@ -54,6 +54,9 @@ public:
     ~ZipOutputEntry();
 
     css::uno::Sequence< sal_Int8 > getData();
+    ZipEntry* getZipEntry() { return m_pCurrentEntry; }
+    ZipPackageStream* getZipPackageStream() { return m_pCurrentStream; }
+    bool isEncrypt() { return m_bEncryptCurrentEntry; }
 
     void closeEntry();
     void write(const css::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength);
diff --git a/package/inc/ZipOutputStream.hxx b/package/inc/ZipOutputStream.hxx
index f11b883..ddc921d 100644
--- a/package/inc/ZipOutputStream.hxx
+++ b/package/inc/ZipOutputStream.hxx
@@ -23,10 +23,12 @@
 #include <com/sun/star/io/XOutputStream.hpp>
 
 #include <ByteChucker.hxx>
+#include <osl/thread.hxx>
 
 #include <vector>
 
 struct ZipEntry;
+class ZipOutputEntry;
 class ZipPackageStream;
 
 class ZipOutputStream
@@ -35,14 +37,17 @@ class ZipOutputStream
     ::std::vector < ZipEntry * > m_aZipList;
 
     ByteChucker         m_aChucker;
-    bool                m_bFinished;
     ZipEntry            *m_pCurrentEntry;
+    std::vector< osl::Thread* > m_aWorkers;
+    std::vector< ZipOutputEntry* > m_aEntries;
 
 public:
     ZipOutputStream(
         const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > &xOStream );
     ~ZipOutputStream();
 
+    void addDeflatingThread( ZipOutputEntry *pEntry, osl::Thread *pThread );
+
     void writeLOC( ZipEntry *pEntry, bool bEncrypt = false )
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
     void rawWrite( ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
diff --git a/package/inc/ZipPackageStream.hxx b/package/inc/ZipPackageStream.hxx
index 8f9b76a..b639a1f 100644
--- a/package/inc/ZipPackageStream.hxx
+++ b/package/inc/ZipPackageStream.hxx
@@ -63,14 +63,13 @@ private:
     sal_uInt8   m_nStreamMode;
     sal_uInt32  m_nMagicalHackPos;
     sal_uInt32  m_nMagicalHackSize;
+    sal_Int64   m_nOwnStreamOrigSize;
 
     bool m_bHasSeekable;
-
     bool m_bCompressedIsSetFromOutside;
-
     bool m_bFromManifest;
-
     bool m_bUseWinEncoding;
+    bool m_bRawStream;
 
     ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > GetOwnSeekStream();
 
@@ -138,6 +137,7 @@ public:
     void setZipEntryOnLoading( const ZipEntry &rInEntry);
     ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawData()
         throw(::com::sun::star::uno::RuntimeException);
+    void successfullyWritten( ZipEntry *pEntry );
 
     static ::com::sun::star::uno::Sequence < sal_Int8 > static_getImplementationId();
 
diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx
index f43b5c7..a5fbe25 100644
--- a/package/source/zipapi/ZipOutputEntry.cxx
+++ b/package/source/zipapi/ZipOutputEntry.cxx
@@ -47,14 +47,13 @@ ZipOutputEntry::ZipOutputEntry( const uno::Reference< uno::XComponentContext >&
 , m_pCurrentEntry(&rEntry)
 , m_nDigested(0)
 , m_bEncryptCurrentEntry(bEncrypt)
-, m_pCurrentStream(NULL)
+, m_pCurrentStream(pStream)
 {
     assert(m_pCurrentEntry->nMethod == DEFLATED && "Use ZipPackageStream::rawWrite() for STORED entries");
     if (m_bEncryptCurrentEntry)
     {
         m_xCipherContext = ZipFile::StaticGetCipher( rxContext, pStream->GetEncryptionData(), true );
         m_xDigestContext = ZipFile::StaticGetDigestContextForChecksum( rxContext, pStream->GetEncryptionData() );
-        m_pCurrentStream = pStream;
     }
 }
 
diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx
index c9b6e08..c191b34 100644
--- a/package/source/zipapi/ZipOutputStream.cxx
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -27,6 +27,7 @@
 
 #include <PackageConstants.hxx>
 #include <ZipEntry.hxx>
+#include <ZipOutputEntry.hxx>
 #include <ZipPackageStream.hxx>
 
 using namespace com::sun::star;
@@ -39,15 +40,12 @@ using namespace com::sun::star::packages::zip::ZipConstants;
 ZipOutputStream::ZipOutputStream( const uno::Reference < io::XOutputStream > &xOStream )
 : m_xStream(xOStream)
 , m_aChucker(xOStream)
-, m_bFinished(false)
 , m_pCurrentEntry(NULL)
 {
 }
 
 ZipOutputStream::~ZipOutputStream( void )
 {
-    for (sal_Int32 i = 0, nEnd = m_aZipList.size(); i < nEnd; i++)
-        delete m_aZipList[i];
 }
 
 void ZipOutputStream::setEntry( ZipEntry *pEntry )
@@ -66,6 +64,13 @@ void ZipOutputStream::setEntry( ZipEntry *pEntry )
     }
 }
 
+void ZipOutputStream::addDeflatingThread( ZipOutputEntry *pEntry, osl::Thread *pThread )
+{
+    m_aWorkers.push_back(pThread);
+    m_aEntries.push_back(pEntry);
+    pThread->create();
+}
+
 void ZipOutputStream::rawWrite( Sequence< sal_Int8 >& rBuffer, sal_Int32 /*nNewOffset*/, sal_Int32 nNewLength )
     throw(IOException, RuntimeException)
 {
@@ -85,21 +90,38 @@ void ZipOutputStream::rawCloseEntry( bool bEncrypt )
     m_pCurrentEntry = NULL;
 }
 
-void ZipOutputStream::finish(  )
+void ZipOutputStream::finish()
     throw(IOException, RuntimeException)
 {
-    if (m_bFinished)
-        return;
+    assert(!m_aZipList.empty() && "Zip file must have at least one entry!");
 
-    if (m_aZipList.size() < 1)
-        OSL_FAIL("Zip file must have at least one entry!\n");
+    // Wait for all threads to finish & write
+    for (size_t i = 0; i < m_aWorkers.size(); i++)
+    {
+        m_aWorkers[i]->join();
+        delete m_aWorkers[i];
+    }
+
+    for (size_t i = 0; i < m_aEntries.size(); i++)
+    {
+        writeLOC(m_aEntries[i]->getZipEntry(), m_aEntries[i]->isEncrypt());
+        uno::Sequence< sal_Int8 > aCompressedData = m_aEntries[i]->getData();
+        rawWrite(aCompressedData, 0, aCompressedData.getLength());
+        rawCloseEntry(m_aEntries[i]->isEncrypt());
+
+        m_aEntries[i]->getZipPackageStream()->successfullyWritten(m_aEntries[i]->getZipEntry());
+        delete m_aEntries[i];
+    }
 
     sal_Int32 nOffset= static_cast < sal_Int32 > (m_aChucker.GetPosition());
-    for (sal_Int32 i =0, nEnd = m_aZipList.size(); i < nEnd; i++)
+    for (size_t i = 0; i < m_aZipList.size(); i++)
+    {
         writeCEN( *m_aZipList[i] );
+        delete m_aZipList[i];
+    }
     writeEND( nOffset, static_cast < sal_Int32 > (m_aChucker.GetPosition()) - nOffset);
-    m_bFinished = true;
     m_xStream->flush();
+    m_aZipList.clear();
 }
 
 void ZipOutputStream::writeEND(sal_uInt32 nOffset, sal_uInt32 nLength)
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index acec90b..c65d903 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -90,10 +90,12 @@ ZipPackageStream::ZipPackageStream ( ZipPackage & rNewPackage,
 , m_nStreamMode( PACKAGE_STREAM_NOTSET )
 , m_nMagicalHackPos( 0 )
 , m_nMagicalHackSize( 0 )
+, m_nOwnStreamOrigSize( 0 )
 , m_bHasSeekable( false )
 , m_bCompressedIsSetFromOutside( false )
 , m_bFromManifest( false )
 , m_bUseWinEncoding( false )
+, m_bRawStream( false )
 {
     m_xContext = xContext;
     m_nFormat = nFormat;
@@ -437,6 +439,35 @@ bool ZipPackageStream::ParsePackageRawStream()
     return true;
 }
 
+class DeflateThread: public osl::Thread
+{
+    ZipOutputEntry *mpEntry;
+    uno::Reference< io::XInputStream > mxInStream;
+
+public:
+    DeflateThread( ZipOutputEntry *pEntry,
+                   const uno::Reference< io::XInputStream >& xInStream )
+        : mpEntry(pEntry)
+        , mxInStream(xInStream)
+    {}
+
+private:
+    virtual void SAL_CALL run() SAL_OVERRIDE
+    {
+        sal_Int32 nLength = 0;
+        uno::Sequence< sal_Int8 > aSeq(n_ConstBufferSize);
+        do
+        {
+            nLength = mxInStream->readBytes(aSeq, n_ConstBufferSize);
+            mpEntry->write(aSeq, 0, nLength);
+        }
+        while (nLength == n_ConstBufferSize);
+        mpEntry->closeEntry();
+
+        mxInStream.clear();
+    }
+};
+
 static void ImplSetStoredData( ZipEntry & rEntry, uno::Reference< io::XInputStream> & rStream )
 {
     // It's very annoying that we have to do this, but lots of zip packages
@@ -497,20 +528,21 @@ bool ZipPackageStream::saveChild(
 
     OSL_ENSURE( m_nStreamMode != PACKAGE_STREAM_NOTSET, "Unacceptable ZipPackageStream mode!" );
 
-    bool bRawStream = false;
+    m_bRawStream = false;
     if ( m_nStreamMode == PACKAGE_STREAM_DETECT )
-        bRawStream = ParsePackageRawStream();
+        m_bRawStream = ParsePackageRawStream();
     else if ( m_nStreamMode == PACKAGE_STREAM_RAW )
-        bRawStream = true;
+        m_bRawStream = true;
 
+    bool bParallelDeflate = false;
     bool bTransportOwnEncrStreamAsRaw = false;
     // During the storing the original size of the stream can be changed
     // TODO/LATER: get rid of this hack
-    sal_Int64 nOwnStreamOrigSize = bRawStream ? m_nMagicalHackSize : aEntry.nSize;
+    m_nOwnStreamOrigSize = m_bRawStream ? m_nMagicalHackSize : aEntry.nSize;
 
     bool bUseNonSeekableAccess = false;
     uno::Reference < io::XInputStream > xStream;
-    if ( !IsPackageMember() && !bRawStream && !bToBeEncrypted && bToBeCompressed )
+    if ( !IsPackageMember() && !m_bRawStream && !bToBeEncrypted && bToBeCompressed )
     {
         // the stream is not a package member, not a raw stream,
         // it should not be encrypted and it should be compressed,
@@ -540,11 +572,11 @@ bool ZipPackageStream::saveChild(
             {
                 // If the stream is a raw one, then we should be positioned
                 // at the beginning of the actual data
-                if ( !bToBeCompressed || bRawStream )
+                if ( !bToBeCompressed || m_bRawStream )
                 {
                     // The raw stream can neither be encrypted nor connected
-                    OSL_ENSURE( !bRawStream || !(bToBeCompressed || bToBeEncrypted), "The stream is already encrypted!\n" );
-                    xSeek->seek ( bRawStream ? m_nMagicalHackPos : 0 );
+                    OSL_ENSURE( !m_bRawStream || !(bToBeCompressed || bToBeEncrypted), "The stream is already encrypted!\n" );
+                    xSeek->seek ( m_bRawStream ? m_nMagicalHackPos : 0 );
                     ImplSetStoredData ( *pTempEntry, xStream );
 
                     // TODO/LATER: Get rid of hacks related to switching of Flag Method and Size properties!
@@ -553,7 +585,7 @@ bool ZipPackageStream::saveChild(
                 {
                     // this is the correct original size
                     pTempEntry->nSize = xSeek->getLength();
-                    nOwnStreamOrigSize = pTempEntry->nSize;
+                    m_nOwnStreamOrigSize = pTempEntry->nSize;
                 }
 
                 xSeek->seek ( 0 );
@@ -592,7 +624,7 @@ bool ZipPackageStream::saveChild(
             return bSuccess;
         }
 
-        if ( bToBeEncrypted || bRawStream || bTransportOwnEncrStreamAsRaw )
+        if ( bToBeEncrypted || m_bRawStream || bTransportOwnEncrStreamAsRaw )
         {
             if ( bToBeEncrypted && !bTransportOwnEncrStreamAsRaw )
             {
@@ -624,11 +656,11 @@ bool ZipPackageStream::saveChild(
             aPropSet[PKG_MNFST_ITERATION].Value <<= m_xBaseEncryptionData->m_nIterationCount;
 
             // Need to store the uncompressed size in the manifest
-            OSL_ENSURE( nOwnStreamOrigSize >= 0, "The stream size was not correctly initialized!\n" );
+            OSL_ENSURE( m_nOwnStreamOrigSize >= 0, "The stream size was not correctly initialized!\n" );
             aPropSet[PKG_MNFST_UCOMPSIZE].Name = sSizeProperty;
-            aPropSet[PKG_MNFST_UCOMPSIZE].Value <<= nOwnStreamOrigSize;
+            aPropSet[PKG_MNFST_UCOMPSIZE].Value <<= m_nOwnStreamOrigSize;
 
-            if ( bRawStream || bTransportOwnEncrStreamAsRaw )
+            if ( m_bRawStream || bTransportOwnEncrStreamAsRaw )
             {
                 ::rtl::Reference< EncryptionData > xEncData = GetEncryptionData();
                 if ( !xEncData.is() )
@@ -651,7 +683,7 @@ bool ZipPackageStream::saveChild(
     // If the entry is already stored in the zip file in the format we
     // want for this write...copy it raw
     if ( !bUseNonSeekableAccess
-      && ( bRawStream || bTransportOwnEncrStreamAsRaw
+      && ( m_bRawStream || bTransportOwnEncrStreamAsRaw
         || ( IsPackageMember() && !bToBeEncrypted
           && ( ( aEntry.nMethod == DEFLATED && bToBeCompressed )
             || ( aEntry.nMethod == STORED && !bToBeCompressed ) ) ) ) )
@@ -671,7 +703,7 @@ bool ZipPackageStream::saveChild(
 
         try
         {
-            if ( bRawStream )
+            if ( m_bRawStream )
                 xStream->skipBytes( m_nMagicalHackPos );
 
             ZipOutputStream::setEntry(pTempEntry);
@@ -733,35 +765,29 @@ bool ZipPackageStream::saveChild(
         try
         {
             ZipOutputStream::setEntry(pTempEntry);
-            rZipOut.writeLOC(pTempEntry, bToBeEncrypted);
             // the entry is provided to the ZipOutputStream that will delete it
             pAutoTempEntry.release();
-            sal_Int32 nLength;
-            uno::Sequence < sal_Int8 > aSeq (n_ConstBufferSize);
 
             if (pTempEntry->nMethod == STORED)
             {
+                sal_Int32 nLength;
+                uno::Sequence< sal_Int8 > aSeq(n_ConstBufferSize);
+                rZipOut.writeLOC(pTempEntry, bToBeEncrypted);
                 do
                 {
                     nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
                     rZipOut.rawWrite(aSeq, 0, nLength);
                 }
                 while ( nLength == n_ConstBufferSize );
+                rZipOut.rawCloseEntry(bToBeEncrypted);
             }
             else
             {
-                ZipOutputEntry aZipEntry(m_xContext, *pTempEntry, this, bToBeEncrypted);
-                do
-                {
-                    nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
-                    aZipEntry.write(aSeq, 0, nLength);
-                }
-                while ( nLength == n_ConstBufferSize );
-                aZipEntry.closeEntry();
-                uno::Sequence< sal_Int8 > aCompressedData = aZipEntry.getData();
-                rZipOut.rawWrite(aCompressedData, 0, aCompressedData.getLength());
+                bParallelDeflate = true;
+                // Start a new thread deflating this zip entry
+                ZipOutputEntry *pZipEntry = new ZipOutputEntry(m_xContext, *pTempEntry, this, bToBeEncrypted);
+                rZipOut.addDeflatingThread( pZipEntry, new DeflateThread(pZipEntry, xStream) );
             }
-            rZipOut.rawCloseEntry(bToBeEncrypted);
         }
         catch ( ZipException& )
         {
@@ -793,36 +819,39 @@ bool ZipPackageStream::saveChild(
         }
     }
 
-    if( bSuccess )
-    {
-        if ( !IsPackageMember() )
-        {
-            CloseOwnStreamIfAny();
-            SetPackageMember ( true );
-        }
+    if (bSuccess && !bParallelDeflate)
+        successfullyWritten(pTempEntry);
 
-        if ( bRawStream )
-        {
-            // the raw stream was integrated and now behaves
-            // as usual encrypted stream
-            SetToBeEncrypted( true );
-        }
+    if ( aPropSet.getLength()
+      && ( m_nFormat == embed::StorageFormats::PACKAGE || m_nFormat == embed::StorageFormats::OFOPXML ) )
+        rManList.push_back( aPropSet );
 
-        // Then copy it back afterwards...
-        ZipPackageFolder::copyZipEntry ( aEntry, *pTempEntry );
+    return bSuccess;
+}
 
-        // TODO/LATER: get rid of this hack ( the encrypted stream size property is changed during saving )
-        if ( IsEncrypted() )
-            setSize( nOwnStreamOrigSize );
+void ZipPackageStream::successfullyWritten( ZipEntry *pEntry )
+{
+    if ( !IsPackageMember() )
+    {
+        CloseOwnStreamIfAny();
+        SetPackageMember ( true );
+    }
 
-        aEntry.nOffset *= -1;
+    if ( m_bRawStream )
+    {
+        // the raw stream was integrated and now behaves
+        // as usual encrypted stream
+        SetToBeEncrypted( true );
     }
 
-    if ( aPropSet.getLength()
-      && ( m_nFormat == embed::StorageFormats::PACKAGE || m_nFormat == embed::StorageFormats::OFOPXML ) )
-        rManList.push_back( aPropSet );
+    // Then copy it back afterwards...
+    ZipPackageFolder::copyZipEntry( aEntry, *pEntry );
 
-    return bSuccess;
+    // TODO/LATER: get rid of this hack ( the encrypted stream size property is changed during saving )
+    if ( IsEncrypted() )
+        setSize( m_nOwnStreamOrigSize );
+
+    aEntry.nOffset *= -1;
 }
 
 void ZipPackageStream::SetPackageMember( bool bNewValue )
diff --git a/package/source/zippackage/wrapstreamforshare.cxx b/package/source/zippackage/wrapstreamforshare.cxx
index 4f737bf..c74e4b2 100644
--- a/package/source/zippackage/wrapstreamforshare.cxx
+++ b/package/source/zippackage/wrapstreamforshare.cxx
@@ -54,8 +54,6 @@ sal_Int32 SAL_CALL WrapStreamForShare::readBytes( uno::Sequence< sal_Int8 >& aDa
                 io::IOException,
                 uno::RuntimeException, std::exception )
 {
-    ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
-
     if ( !m_xInStream.is() )
         throw io::IOException(THROW_WHERE );
 
@@ -73,8 +71,6 @@ sal_Int32 SAL_CALL WrapStreamForShare::readSomeBytes( uno::Sequence< sal_Int8 >&
                 io::IOException,
                 uno::RuntimeException, std::exception )
 {
-    ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
-
     if ( !m_xInStream.is() )
         throw io::IOException(THROW_WHERE );
 
commit 3bfa5a6355eb06496f03410cf3f651382915f2e8
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Tue Oct 21 10:37:02 2014 +0200

    package: Call writeLOC always after putNextEntry explicitly
    
    Preparation step to parallel deflating.
    Rename putNextEntry to setEntry and make it a static function.
    We need to call setEntry before starting thread but writeLOC after.
    
    Change-Id: I99a9ffa7dc4c18b47c621847b48bf8469bfb789a

diff --git a/package/inc/ZipOutputStream.hxx b/package/inc/ZipOutputStream.hxx
index 2d78eb7..f11b883 100644
--- a/package/inc/ZipOutputStream.hxx
+++ b/package/inc/ZipOutputStream.hxx
@@ -37,33 +37,30 @@ class ZipOutputStream
     ByteChucker         m_aChucker;
     bool                m_bFinished;
     ZipEntry            *m_pCurrentEntry;
-    bool                m_bEncrypt;
 
 public:
     ZipOutputStream(
         const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > &xOStream );
     ~ZipOutputStream();
 
-    // rawWrite to support a direct write to the output stream
+    void writeLOC( ZipEntry *pEntry, bool bEncrypt = false )
+        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
     void rawWrite( ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
-    void rawCloseEntry()
+    void rawCloseEntry( bool bEncrypt = false )
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
 
-    void putNextEntry( ZipEntry& rEntry, bool bEncrypt = false )
-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
     void finish()
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
 
     static sal_uInt32 getCurrentDosTime();
+    static void setEntry( ZipEntry *pEntry );
 
 private:
     void writeEND(sal_uInt32 nOffset, sal_uInt32 nLength)
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
     void writeCEN( const ZipEntry &rEntry )
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
-    sal_Int32 writeLOC( const ZipEntry &rEntry )
-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
     void writeEXT( const ZipEntry &rEntry )
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
 };
diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx
index 25cdb18..c9b6e08 100644
--- a/package/source/zipapi/ZipOutputStream.cxx
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -50,28 +50,20 @@ ZipOutputStream::~ZipOutputStream( void )
         delete m_aZipList[i];
 }
 
-void ZipOutputStream::putNextEntry( ZipEntry& rEntry, bool bEncrypt )
-    throw(IOException, RuntimeException)
+void ZipOutputStream::setEntry( ZipEntry *pEntry )
 {
-    assert(!m_pCurrentEntry && "Forgot to close an entry before putNextEntry()?");
-    if (rEntry.nTime == -1)
-        rEntry.nTime = getCurrentDosTime();
-    if (rEntry.nMethod == -1)
-        rEntry.nMethod = DEFLATED;
-    rEntry.nVersion = 20;
-    rEntry.nFlag = 1 << 11;
-    if (rEntry.nSize == -1 || rEntry.nCompressedSize == -1 ||
-        rEntry.nCrc == -1)
+    if (pEntry->nTime == -1)
+        pEntry->nTime = getCurrentDosTime();
+    if (pEntry->nMethod == -1)
+        pEntry->nMethod = DEFLATED;
+    pEntry->nVersion = 20;
+    pEntry->nFlag = 1 << 11;
+    if (pEntry->nSize == -1 || pEntry->nCompressedSize == -1 ||
+        pEntry->nCrc == -1)
     {
-        rEntry.nSize = rEntry.nCompressedSize = 0;
-        rEntry.nFlag |= 8;
+        pEntry->nSize = pEntry->nCompressedSize = 0;
+        pEntry->nFlag |= 8;
     }
-    m_bEncrypt = bEncrypt;
-
-    sal_Int32 nLOCLength = writeLOC(rEntry);
-    rEntry.nOffset = m_aChucker.GetPosition() - nLOCLength;
-    m_aZipList.push_back( &rEntry );
-    m_pCurrentEntry = &rEntry;
 }
 
 void ZipOutputStream::rawWrite( Sequence< sal_Int8 >& rBuffer, sal_Int32 /*nNewOffset*/, sal_Int32 nNewLength )
@@ -80,13 +72,14 @@ void ZipOutputStream::rawWrite( Sequence< sal_Int8 >& rBuffer, sal_Int32 /*nNewO
     m_aChucker.WriteBytes( Sequence< sal_Int8 >(rBuffer.getConstArray(), nNewLength) );
 }
 
-void ZipOutputStream::rawCloseEntry()
+void ZipOutputStream::rawCloseEntry( bool bEncrypt )
     throw(IOException, RuntimeException)
 {
+    assert(m_pCurrentEntry && "Forgot to call writeLOC()?");
     if ( m_pCurrentEntry->nMethod == DEFLATED && ( m_pCurrentEntry->nFlag & 8 ) )
         writeEXT(*m_pCurrentEntry);
 
-    if (m_bEncrypt)
+    if (bEncrypt)
         m_pCurrentEntry->nMethod = STORED;
 
     m_pCurrentEntry = NULL;
@@ -192,9 +185,14 @@ void ZipOutputStream::writeEXT( const ZipEntry &rEntry )
     }
 }
 
-sal_Int32 ZipOutputStream::writeLOC( const ZipEntry &rEntry )
+void ZipOutputStream::writeLOC( ZipEntry *pEntry, bool bEncrypt )
     throw(IOException, RuntimeException)
 {
+    assert(!m_pCurrentEntry && "Forgot to close an entry with rawCloseEntry()?");
+    m_pCurrentEntry = pEntry;
+    m_aZipList.push_back( m_pCurrentEntry );
+    const ZipEntry &rEntry = *m_pCurrentEntry;
+
     if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( rEntry.sPath, true ) )
         throw IOException("Unexpected character is used in file name." );
 
@@ -206,7 +204,7 @@ sal_Int32 ZipOutputStream::writeLOC( const ZipEntry &rEntry )
 
     m_aChucker << rEntry.nFlag;
     // If it's an encrypted entry, we pretend its stored plain text
-    if (m_bEncrypt)
+    if (bEncrypt)
         m_aChucker << static_cast < sal_Int16 > ( STORED );
     else
         m_aChucker << rEntry.nMethod;
@@ -240,7 +238,7 @@ sal_Int32 ZipOutputStream::writeLOC( const ZipEntry &rEntry )
     Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() );
     m_aChucker.WriteBytes( aSequence );
 
-    return LOCHDR + nNameLength;
+    m_pCurrentEntry->nOffset = m_aChucker.GetPosition() - (LOCHDR + nNameLength);
 }
 
 sal_uInt32 ZipOutputStream::getCurrentDosTime()
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
index c67e193..bc69704 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -984,7 +984,8 @@ void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut )
 
     try
     {
-        aZipOut.putNextEntry(*pEntry);
+        ZipOutputStream::setEntry(pEntry);
+        aZipOut.writeLOC(pEntry);
         aZipOut.rawWrite(aType, 0, nBufferLength);
         aZipOut.rawCloseEntry();
     }
@@ -1026,7 +1027,8 @@ void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< uno::Seq
     pBuffer->realloc( nBufferLength );
 
     // the manifest.xml is never encrypted - so pass an empty reference
-    aZipOut.putNextEntry(*pEntry);
+    ZipOutputStream::setEntry(pEntry);
+    aZipOut.writeLOC(pEntry);
     ZipOutputEntry aZipEntry(m_xContext, *pEntry, NULL);
     aZipEntry.write(pBuffer->getSequence(), 0, nBufferLength);
     aZipEntry.closeEntry();
@@ -1080,7 +1082,8 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno:
     pBuffer->realloc( nBufferLength );
 
     // there is no encryption in this format currently
-    aZipOut.putNextEntry(*pEntry);
+    ZipOutputStream::setEntry(pEntry);
+    aZipOut.writeLOC(pEntry);
     ZipOutputEntry aZipEntry(m_xContext, *pEntry, NULL);
     aZipEntry.write(pBuffer->getSequence(), 0, nBufferLength);
     aZipEntry.closeEntry();
diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx
index a6b2e5c..cb72ed1 100644
--- a/package/source/zippackage/ZipPackageFolder.cxx
+++ b/package/source/zippackage/ZipPackageFolder.cxx
@@ -337,7 +337,8 @@ void ZipPackageFolder::saveContents(
 
         try
         {
-            rZipOut.putNextEntry( *pTempEntry );
+            ZipOutputStream::setEntry(pTempEntry);
+            rZipOut.writeLOC(pTempEntry);
             rZipOut.rawCloseEntry();
         }
         catch ( ZipException& )
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index 94e7089..acec90b 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -674,7 +674,8 @@ bool ZipPackageStream::saveChild(
             if ( bRawStream )
                 xStream->skipBytes( m_nMagicalHackPos );
 
-            rZipOut.putNextEntry(*pTempEntry);
+            ZipOutputStream::setEntry(pTempEntry);
+            rZipOut.writeLOC(pTempEntry);
             // the entry is provided to the ZipOutputStream that will delete it
             pAutoTempEntry.release();
 
@@ -731,7 +732,8 @@ bool ZipPackageStream::saveChild(
 
         try
         {
-            rZipOut.putNextEntry(*pTempEntry, bToBeEncrypted);
+            ZipOutputStream::setEntry(pTempEntry);
+            rZipOut.writeLOC(pTempEntry, bToBeEncrypted);
             // the entry is provided to the ZipOutputStream that will delete it
             pAutoTempEntry.release();
             sal_Int32 nLength;
@@ -759,7 +761,7 @@ bool ZipPackageStream::saveChild(
                 uno::Sequence< sal_Int8 > aCompressedData = aZipEntry.getData();
                 rZipOut.rawWrite(aCompressedData, 0, aCompressedData.getLength());
             }
-            rZipOut.rawCloseEntry();
+            rZipOut.rawCloseEntry(bToBeEncrypted);
         }
         catch ( ZipException& )
         {
commit 1a74cf3b8c71c36c98f8db8cd304c5c0315a1f3d
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Tue Oct 21 12:21:22 2014 +0200

    package: Do not use hacky bit 1<<4 in ZipEntry::nFlag
    
    Change-Id: I504f5c0c9aa9b655ffb53d9820a33677dad6aa08

diff --git a/package/inc/ZipOutputStream.hxx b/package/inc/ZipOutputStream.hxx
index 0c8dafe..2d78eb7 100644
--- a/package/inc/ZipOutputStream.hxx
+++ b/package/inc/ZipOutputStream.hxx
@@ -37,6 +37,7 @@ class ZipOutputStream
     ByteChucker         m_aChucker;
     bool                m_bFinished;
     ZipEntry            *m_pCurrentEntry;
+    bool                m_bEncrypt;
 
 public:
     ZipOutputStream(
diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx
index d4f0456..25cdb18 100644
--- a/package/source/zipapi/ZipOutputStream.cxx
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -66,10 +66,7 @@ void ZipOutputStream::putNextEntry( ZipEntry& rEntry, bool bEncrypt )
         rEntry.nSize = rEntry.nCompressedSize = 0;
         rEntry.nFlag |= 8;
     }
-    if (bEncrypt)
-    {
-        rEntry.nFlag |= 1 << 4;
-    }
+    m_bEncrypt = bEncrypt;
 
     sal_Int32 nLOCLength = writeLOC(rEntry);
     rEntry.nOffset = m_aChucker.GetPosition() - nLOCLength;
@@ -88,6 +85,10 @@ void ZipOutputStream::rawCloseEntry()
 {
     if ( m_pCurrentEntry->nMethod == DEFLATED && ( m_pCurrentEntry->nFlag & 8 ) )
         writeEXT(*m_pCurrentEntry);
+
+    if (m_bEncrypt)
+        m_pCurrentEntry->nMethod = STORED;
+
     m_pCurrentEntry = NULL;
 }
 
@@ -144,19 +145,8 @@ void ZipOutputStream::writeCEN( const ZipEntry &rEntry )
     m_aChucker << CENSIG;
     m_aChucker << rEntry.nVersion;
     m_aChucker << rEntry.nVersion;
-    if (rEntry.nFlag & (1 << 4) )
-    {
-        // If it's an encrypted entry, we pretend its stored plain text
-        ZipEntry *pEntry = const_cast < ZipEntry * > ( &rEntry );
-        pEntry->nFlag &= ~(1 <<4 );
-        m_aChucker << rEntry.nFlag;
-        m_aChucker << static_cast < sal_Int16 > ( STORED );
-    }
-    else
-    {
-        m_aChucker << rEntry.nFlag;
-        m_aChucker << rEntry.nMethod;
-    }
+    m_aChucker << rEntry.nFlag;
+    m_aChucker << rEntry.nMethod;
     bool bWrite64Header = false;
 
     m_aChucker << static_cast < sal_uInt32> ( rEntry.nTime );
@@ -214,19 +204,12 @@ sal_Int32 ZipOutputStream::writeLOC( const ZipEntry &rEntry )
     m_aChucker << LOCSIG;
     m_aChucker << rEntry.nVersion;
 
-    if (rEntry.nFlag & (1 << 4) )
-    {
-        // If it's an encrypted entry, we pretend its stored plain text
-        sal_Int16 nTmpFlag = rEntry.nFlag;
-        nTmpFlag &= ~(1 <<4 );
-        m_aChucker << nTmpFlag;
+    m_aChucker << rEntry.nFlag;
+    // If it's an encrypted entry, we pretend its stored plain text
+    if (m_bEncrypt)
         m_aChucker << static_cast < sal_Int16 > ( STORED );
-    }
     else
-    {
-        m_aChucker << rEntry.nFlag;
         m_aChucker << rEntry.nMethod;
-    }
 
     bool bWrite64Header = false;
 
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index ad7596d..94e7089 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -809,13 +809,6 @@ bool ZipPackageStream::saveChild(
         // Then copy it back afterwards...
         ZipPackageFolder::copyZipEntry ( aEntry, *pTempEntry );
 
-        // Remove hacky bit from entry flags
-        if ( aEntry.nFlag & ( 1 << 4 ) )
-        {
-            aEntry.nFlag &= ~( 1 << 4 );
-            aEntry.nMethod = STORED;
-        }
-
         // TODO/LATER: get rid of this hack ( the encrypted stream size property is changed during saving )
         if ( IsEncrypted() )
             setSize( nOwnStreamOrigSize );
commit 95c86f3abd312a2867e83abe2870b4590126b5e9
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Tue Oct 21 09:29:19 2014 +0200

    There is no XZipOutputEntry interface
    
    Change-Id: Ib8fa3351ba25416a13d6c8bf63bd5fc8e43703c5

diff --git a/package/inc/ZipOutputEntry.hxx b/package/inc/ZipOutputEntry.hxx
index e04cebf..c24d5a9 100644
--- a/package/inc/ZipOutputEntry.hxx
+++ b/package/inc/ZipOutputEntry.hxx
@@ -19,7 +19,6 @@
 #ifndef INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX
 #define INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX
 
-#include <com/sun/star/io/IOException.hpp>
 #include <com/sun/star/uno/Reference.hxx>
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <com/sun/star/xml/crypto/XCipherContext.hpp>
@@ -56,11 +55,8 @@ public:
 
     css::uno::Sequence< sal_Int8 > getData();
 
-    // XZipOutputEntry interfaces
-    void SAL_CALL closeEntry(  )
-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
-    void SAL_CALL write( const ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+    void closeEntry();
+    void write(const css::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength);
 
 private:
     void doDeflate();
diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx
index bcbb6eb..f43b5c7 100644
--- a/package/source/zipapi/ZipOutputEntry.cxx
+++ b/package/source/zipapi/ZipOutputEntry.cxx
@@ -68,8 +68,7 @@ uno::Sequence< sal_Int8 > ZipOutputEntry::getData()
     return m_pBuffer->getSequence();
 }
 
-void SAL_CALL ZipOutputEntry::closeEntry()
-    throw(IOException, RuntimeException)
+void ZipOutputEntry::closeEntry()
 {
     m_aDeflater.finish();
     while (!m_aDeflater.finished())
@@ -120,8 +119,7 @@ void SAL_CALL ZipOutputEntry::closeEntry()
     }
 }
 
-void SAL_CALL ZipOutputEntry::write( const Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
-    throw(IOException, RuntimeException)
+void ZipOutputEntry::write( const Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
 {
     if (!m_aDeflater.finished())
     {
commit 59c5919b4b9f8000e5c99b1ea2a3aaecf36803ed
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Tue Oct 21 09:20:24 2014 +0200

    package: Use memory stream for compressing zip entries
    
    Change-Id: Ibf81dc3cd8a9a9da3dfd6ee6e587a522c4d56a44

diff --git a/package/inc/ZipOutputEntry.hxx b/package/inc/ZipOutputEntry.hxx
index 73bd8a4..e04cebf 100644
--- a/package/inc/ZipOutputEntry.hxx
+++ b/package/inc/ZipOutputEntry.hxx
@@ -29,19 +29,19 @@
 #include <CRC32.hxx>
 
 struct ZipEntry;
-class ZipOutputStream;
+class ZipPackageBuffer;
 class ZipPackageStream;
 
 class ZipOutputEntry
 {
     ::com::sun::star::uno::Sequence< sal_Int8 > m_aDeflateBuffer;
-    ZipUtils::Deflater  m_aDeflater;
+    ZipUtils::Deflater m_aDeflater;
+    css::uno::Reference< ZipPackageBuffer > m_pBuffer;
 
     ::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;
 
     CRC32               m_aCRC;
-    ZipOutputStream*    m_pZipOutputStream;
     ZipEntry            *m_pCurrentEntry;
     sal_Int16           m_nDigested;
     bool                m_bEncryptCurrentEntry;
@@ -50,10 +50,12 @@ class ZipOutputEntry
 public:
     ZipOutputEntry(
         const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
-        ZipOutputStream *pZipOutputStream, ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt = false);
+        ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt = false);
 
     ~ZipOutputEntry();
 
+    css::uno::Sequence< sal_Int8 > getData();
+
     // XZipOutputEntry interfaces
     void SAL_CALL closeEntry(  )
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
diff --git a/package/inc/ZipOutputStream.hxx b/package/inc/ZipOutputStream.hxx
index 6775bd0..0c8dafe 100644
--- a/package/inc/ZipOutputStream.hxx
+++ b/package/inc/ZipOutputStream.hxx
@@ -53,7 +53,6 @@ public:
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
     void finish()
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
-    ByteChucker& getChucker();
 
     static sal_uInt32 getCurrentDosTime();
 
diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx
index ca08abb..bcbb6eb 100644
--- a/package/source/zipapi/ZipOutputEntry.cxx
+++ b/package/source/zipapi/ZipOutputEntry.cxx
@@ -24,11 +24,10 @@
 
 #include <osl/time.h>
 
-#include <ByteChucker.hxx>
 #include <PackageConstants.hxx>
 #include <ZipEntry.hxx>
 #include <ZipFile.hxx>
-#include <ZipOutputStream.hxx>
+#include <ZipPackageBuffer.hxx>
 #include <ZipPackageStream.hxx>
 
 using namespace com::sun::star;
@@ -39,13 +38,12 @@ using namespace com::sun::star::packages::zip::ZipConstants;
 /** This class is used to deflate Zip entries
  */
 ZipOutputEntry::ZipOutputEntry( const uno::Reference< uno::XComponentContext >& rxContext,
-                        ZipOutputStream* pOutputStream,
                         ZipEntry& rEntry,
                         ZipPackageStream* pStream,
                         bool bEncrypt)
 : m_aDeflateBuffer(n_ConstBufferSize)
 , m_aDeflater(DEFAULT_COMPRESSION, true)
-, m_pZipOutputStream(pOutputStream)
+, m_pBuffer(new ZipPackageBuffer(n_ConstBufferSize))
 , m_pCurrentEntry(&rEntry)
 , m_nDigested(0)
 , m_bEncryptCurrentEntry(bEncrypt)
@@ -64,6 +62,12 @@ ZipOutputEntry::~ZipOutputEntry( void )
 {
 }
 
+uno::Sequence< sal_Int8 > ZipOutputEntry::getData()
+{
+    m_pBuffer->realloc(m_pBuffer->getPosition());
+    return m_pBuffer->getSequence();
+}
+
 void SAL_CALL ZipOutputEntry::closeEntry()
     throw(IOException, RuntimeException)
 {
@@ -151,7 +155,7 @@ void ZipOutputEntry::doDeflate()
             // FIXME64: uno::Sequence not 64bit safe.
             uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->convertWithCipherContext( aTmpBuffer );
 
-            m_pZipOutputStream->getChucker().WriteBytes( aEncryptionBuffer );
+            m_pBuffer->writeBytes( aEncryptionBuffer );
 
             // the sizes as well as checksum for encrypted streams is calculated here
             m_pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength();
@@ -160,7 +164,7 @@ void ZipOutputEntry::doDeflate()
         }
         else
         {
-            m_pZipOutputStream->getChucker().WriteBytes ( aTmpBuffer );
+            m_pBuffer->writeBytes ( aTmpBuffer );
         }
     }
 
@@ -170,7 +174,7 @@ void ZipOutputEntry::doDeflate()
         uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->finalizeCipherContextAndDispose();
         if ( aEncryptionBuffer.getLength() )
         {
-            m_pZipOutputStream->getChucker().WriteBytes( aEncryptionBuffer );
+            m_pBuffer->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 29c19c4..d4f0456 100644
--- a/package/source/zipapi/ZipOutputStream.cxx
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -108,11 +108,6 @@ void ZipOutputStream::finish(  )
     m_xStream->flush();
 }
 
-ByteChucker& ZipOutputStream::getChucker()
-{
-    return m_aChucker;
-}
-
 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 d202fb0..c67e193 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -1027,9 +1027,11 @@ void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< uno::Seq
 
     // the manifest.xml is never encrypted - so pass an empty reference
     aZipOut.putNextEntry(*pEntry);
-    ZipOutputEntry aZipEntry(m_xContext, &aZipOut, *pEntry, NULL);
+    ZipOutputEntry aZipEntry(m_xContext, *pEntry, NULL);
     aZipEntry.write(pBuffer->getSequence(), 0, nBufferLength);
     aZipEntry.closeEntry();
+    uno::Sequence< sal_Int8 > aCompressedData = aZipEntry.getData();
+    aZipOut.rawWrite(aCompressedData, 0, aCompressedData.getLength());
     aZipOut.rawCloseEntry();
 }
 
@@ -1079,9 +1081,11 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno:
 
     // there is no encryption in this format currently
     aZipOut.putNextEntry(*pEntry);
-    ZipOutputEntry aZipEntry(m_xContext, &aZipOut, *pEntry, NULL);
+    ZipOutputEntry aZipEntry(m_xContext, *pEntry, NULL);
     aZipEntry.write(pBuffer->getSequence(), 0, nBufferLength);
     aZipEntry.closeEntry();
+    uno::Sequence< sal_Int8 > aCompressedData = aZipEntry.getData();
+    aZipOut.rawWrite(aCompressedData, 0, aCompressedData.getLength());
     aZipOut.rawCloseEntry();
 }
 
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index 79aa26a..ad7596d 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -748,7 +748,7 @@ bool ZipPackageStream::saveChild(
             }
             else
             {
-                ZipOutputEntry aZipEntry(m_xContext, &rZipOut, *pTempEntry, this, bToBeEncrypted);
+                ZipOutputEntry aZipEntry(m_xContext, *pTempEntry, this, bToBeEncrypted);
                 do
                 {
                     nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
@@ -756,6 +756,8 @@ bool ZipPackageStream::saveChild(
                 }
                 while ( nLength == n_ConstBufferSize );
                 aZipEntry.closeEntry();
+                uno::Sequence< sal_Int8 > aCompressedData = aZipEntry.getData();
+                rZipOut.rawWrite(aCompressedData, 0, aCompressedData.getLength());
             }
             rZipOut.rawCloseEntry();
         }
commit 74ded0584bcf6be7b21d3c1e563434034d68ffa8
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Mon Oct 20 22:54:49 2014 +0200

    ZipOutputEntry: m_pCurrentEntry is always set
    
    Change-Id: Ib6a69a83f4a378df838b2231b9eba7fba49cd9f1

diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx
index b73f0a2..ca08abb 100644
--- a/package/source/zipapi/ZipOutputEntry.cxx
+++ b/package/source/zipapi/ZipOutputEntry.cxx
@@ -64,62 +64,55 @@ ZipOutputEntry::~ZipOutputEntry( void )
 {
 }
 
-void SAL_CALL ZipOutputEntry::closeEntry(  )
+void SAL_CALL ZipOutputEntry::closeEntry()
     throw(IOException, RuntimeException)
 {
-    ZipEntry *pEntry = m_pCurrentEntry;
-    if (pEntry)
+    m_aDeflater.finish();
+    while (!m_aDeflater.finished())
+        doDeflate();
+
+    if ((m_pCurrentEntry->nFlag & 8) == 0)
     {
-        m_aDeflater.finish();
-        while (!m_aDeflater.finished())
-            doDeflate();
-        if ((pEntry->nFlag & 8) == 0)
+        if (m_pCurrentEntry->nSize != m_aDeflater.getTotalIn())
         {
-            if (pEntry->nSize != m_aDeflater.getTotalIn())
-            {
-                OSL_FAIL("Invalid entry size");
-            }
-            if (pEntry->nCompressedSize != m_aDeflater.getTotalOut())
-            {
-                // Different compression strategies make the merit of this
-                // test somewhat dubious
-                pEntry->nCompressedSize = m_aDeflater.getTotalOut();
-            }
-            if (pEntry->nCrc != m_aCRC.getValue())
-            {
-                OSL_FAIL("Invalid entry CRC-32");
-            }
+            OSL_FAIL("Invalid entry size");
         }
-        else
+        if (m_pCurrentEntry->nCompressedSize != m_aDeflater.getTotalOut())
         {
-            if ( !m_bEncryptCurrentEntry )
-            {
-                pEntry->nSize = m_aDeflater.getTotalIn();
-                pEntry->nCompressedSize = m_aDeflater.getTotalOut();
-            }
-            pEntry->nCrc = m_aCRC.getValue();
+            // Different compression strategies make the merit of this
+            // test somewhat dubious
+            m_pCurrentEntry->nCompressedSize = m_aDeflater.getTotalOut();
         }
-        m_aDeflater.reset();
-        m_aCRC.reset();
-
-        if (m_bEncryptCurrentEntry)
+        if (m_pCurrentEntry->nCrc != m_aCRC.getValue())
         {
-            m_bEncryptCurrentEntry = false;
-
-            m_xCipherContext.clear();
+            OSL_FAIL("Invalid entry CRC-32");
+        }
+    }
+    else
+    {
+        if ( !m_bEncryptCurrentEntry )
+        {
+            m_pCurrentEntry->nSize = m_aDeflater.getTotalIn();
+            m_pCurrentEntry->nCompressedSize = m_aDeflater.getTotalOut();
+        }
+        m_pCurrentEntry->nCrc = m_aCRC.getValue();
+    }
+    m_aDeflater.reset();
+    m_aCRC.reset();
 
-            uno::Sequence< sal_Int8 > aDigestSeq;
-            if ( m_xDigestContext.is() )
-            {
-                aDigestSeq = m_xDigestContext->finalizeDigestAndDispose();
-                m_xDigestContext.clear();
-            }
+    if (m_bEncryptCurrentEntry)
+    {
+        m_xCipherContext.clear();
 
-            if ( m_pCurrentStream )
-                m_pCurrentStream->setDigest( aDigestSeq );
+        uno::Sequence< sal_Int8 > aDigestSeq;
+        if ( m_xDigestContext.is() )
+        {
+            aDigestSeq = m_xDigestContext->finalizeDigestAndDispose();
+            m_xDigestContext.clear();
         }
-        m_pCurrentEntry = NULL;
-        m_pCurrentStream = NULL;
+
+        if ( m_pCurrentStream )
+            m_pCurrentStream->setDigest( aDigestSeq );
     }
 }
 
commit 57f9e0bb6c4d640ee62205703b1c7ec4f12fdbc3
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Mon Oct 20 22:02:48 2014 +0200

    package: Zipping STORED entry is the same as rawWrite and we don't encrypt it
    
    Change-Id: Ie3f8ac261a70c9a2b5182fc7d36938d0a46ec045

diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx
index 4e2f6d4..b73f0a2 100644
--- a/package/source/zipapi/ZipOutputEntry.cxx
+++ b/package/source/zipapi/ZipOutputEntry.cxx
@@ -51,6 +51,7 @@ ZipOutputEntry::ZipOutputEntry( const uno::Reference< uno::XComponentContext >&
 , m_bEncryptCurrentEntry(bEncrypt)
 , m_pCurrentStream(NULL)
 {
+    assert(m_pCurrentEntry->nMethod == DEFLATED && "Use ZipPackageStream::rawWrite() for STORED entries");
     if (m_bEncryptCurrentEntry)
     {
         m_xCipherContext = ZipFile::StaticGetCipher( rxContext, pStream->GetEncryptionData(), true );
@@ -69,49 +70,37 @@ void SAL_CALL ZipOutputEntry::closeEntry(  )
     ZipEntry *pEntry = m_pCurrentEntry;
     if (pEntry)
     {
-        switch (pEntry->nMethod)
+        m_aDeflater.finish();
+        while (!m_aDeflater.finished())
+            doDeflate();
+        if ((pEntry->nFlag & 8) == 0)
         {
-            case DEFLATED:
-                m_aDeflater.finish();
-                while (!m_aDeflater.finished())
-                    doDeflate();
-                if ((pEntry->nFlag & 8) == 0)
-                {
-                    if (pEntry->nSize != m_aDeflater.getTotalIn())
-                    {
-                        OSL_FAIL("Invalid entry size");
-                    }
-                    if (pEntry->nCompressedSize != m_aDeflater.getTotalOut())
-                    {
-                        // Different compression strategies make the merit of this
-                        // test somewhat dubious
-                        pEntry->nCompressedSize = m_aDeflater.getTotalOut();
-                    }
-                    if (pEntry->nCrc != m_aCRC.getValue())
-                    {
-                        OSL_FAIL("Invalid entry CRC-32");
-                    }
-                }
-                else
-                {
-                    if ( !m_bEncryptCurrentEntry )
-                    {
-                        pEntry->nSize = m_aDeflater.getTotalIn();
-                        pEntry->nCompressedSize = m_aDeflater.getTotalOut();
-                    }
-                    pEntry->nCrc = m_aCRC.getValue();
-                }
-                m_aDeflater.reset();
-                m_aCRC.reset();
-                break;
-            case STORED:
-                if (!((pEntry->nFlag & 8) == 0))
-                    OSL_FAIL( "Serious error, one of compressed size, size or CRC was -1 in a STORED stream");
-                break;
-            default:
-                OSL_FAIL("Invalid compression method");
-                break;
+            if (pEntry->nSize != m_aDeflater.getTotalIn())
+            {
+                OSL_FAIL("Invalid entry size");
+            }
+            if (pEntry->nCompressedSize != m_aDeflater.getTotalOut())
+            {
+                // Different compression strategies make the merit of this
+                // test somewhat dubious
+                pEntry->nCompressedSize = m_aDeflater.getTotalOut();
+            }
+            if (pEntry->nCrc != m_aCRC.getValue())
+            {
+                OSL_FAIL("Invalid entry CRC-32");
+            }
         }
+        else
+        {
+            if ( !m_bEncryptCurrentEntry )
+            {
+                pEntry->nSize = m_aDeflater.getTotalIn();
+                pEntry->nCompressedSize = m_aDeflater.getTotalOut();
+            }
+            pEntry->nCrc = m_aCRC.getValue();
+        }
+        m_aDeflater.reset();
+        m_aCRC.reset();
 
         if (m_bEncryptCurrentEntry)
         {
@@ -137,24 +126,13 @@ void SAL_CALL ZipOutputEntry::closeEntry(  )
 void SAL_CALL ZipOutputEntry::write( const Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
     throw(IOException, RuntimeException)
 {
-    switch (m_pCurrentEntry->nMethod)
+    if (!m_aDeflater.finished())
     {
-        case DEFLATED:
-            if (!m_aDeflater.finished())
-            {
-                m_aDeflater.setInputSegment(rBuffer, nNewOffset, nNewLength);
-                 while (!m_aDeflater.needsInput())
-                    doDeflate();
-                if (!m_bEncryptCurrentEntry)
-                    m_aCRC.updateSegment(rBuffer, nNewOffset, nNewLength);
-            }
-            break;
-        case STORED:
-            {
-                Sequence < sal_Int8 > aTmpBuffer ( rBuffer.getConstArray(), nNewLength );
-                m_pZipOutputStream->getChucker().WriteBytes( aTmpBuffer );
-            }
-            break;
+        m_aDeflater.setInputSegment(rBuffer, nNewOffset, nNewLength);
+         while (!m_aDeflater.needsInput())
+            doDeflate();
+        if (!m_bEncryptCurrentEntry)
+            m_aCRC.updateSegment(rBuffer, nNewOffset, nNewLength);
     }
 }
 
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
index 5c12cf0..d202fb0 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -985,9 +985,7 @@ void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut )
     try
     {
         aZipOut.putNextEntry(*pEntry);
-        ZipOutputEntry aZipEntry(m_xContext, &aZipOut, *pEntry, NULL);
-        aZipEntry.write(aType, 0, nBufferLength);
-        aZipEntry.closeEntry();
+        aZipOut.rawWrite(aType, 0, nBufferLength);
         aZipOut.rawCloseEntry();
     }
     catch ( const ::com::sun::star::io::IOException & r )
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index 8d433ad..79aa26a 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -485,8 +485,8 @@ bool ZipPackageStream::saveChild(
     pTempEntry->sPath = rPath;
     pTempEntry->nPathLen = (sal_Int16)( OUStringToOString( pTempEntry->sPath, RTL_TEXTENCODING_UTF8 ).getLength() );
 
-    bool bToBeEncrypted = m_bToBeEncrypted && (rEncryptionKey.getLength() || m_bHaveOwnKey);
-    bool bToBeCompressed = bToBeEncrypted ? sal_True : m_bToBeCompressed;
+    const bool bToBeEncrypted = m_bToBeEncrypted && (rEncryptionKey.getLength() || m_bHaveOwnKey);
+    const bool bToBeCompressed = bToBeEncrypted ? sal_True : m_bToBeCompressed;
 
     aPropSet[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty;
     aPropSet[PKG_MNFST_MEDIATYPE].Value <<= GetMediaType( );
@@ -732,20 +732,31 @@ bool ZipPackageStream::saveChild(
         try
         {
             rZipOut.putNextEntry(*pTempEntry, bToBeEncrypted);
-            ZipOutputEntry aZipEntry(m_xContext, &rZipOut, *pTempEntry, this, bToBeEncrypted);
             // the entry is provided to the ZipOutputStream that will delete it
             pAutoTempEntry.release();
-
             sal_Int32 nLength;
             uno::Sequence < sal_Int8 > aSeq (n_ConstBufferSize);
-            do
+
+            if (pTempEntry->nMethod == STORED)
             {
-                nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
-                aZipEntry.write(aSeq, 0, nLength);
+                do
+                {
+                    nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
+                    rZipOut.rawWrite(aSeq, 0, nLength);
+                }
+                while ( nLength == n_ConstBufferSize );
+            }
+            else
+            {
+                ZipOutputEntry aZipEntry(m_xContext, &rZipOut, *pTempEntry, this, bToBeEncrypted);
+                do
+                {
+                    nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
+                    aZipEntry.write(aSeq, 0, nLength);
+                }
+                while ( nLength == n_ConstBufferSize );
+                aZipEntry.closeEntry();
             }
-            while ( nLength == n_ConstBufferSize );
-
-            aZipEntry.closeEntry();
             rZipOut.rawCloseEntry();
         }
         catch ( ZipException& )
commit 906e76b09ebfe98161a74e398b42c655c8971cab
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Mon Oct 20 21:13:50 2014 +0200

    package: Move most ZipOutputEntry's methods back to ZipOutputStream
    
    We want to use ZipOutputEntry only for deflating (and maybe rename it).
    ca13a9377e4a36436e4c82bb33648d0f3b6db6f5 was not a good idea because the
    data still needs to be written sequentially anyway. Otherwise it's hard
    to get offset positions of individual entries right.
    
    Since this commit rawCloseEntry needs to be called always; also when we
    use write&closeEntry because we don't call writeEXT in closeEntry
    anymore.
    Need to rename and add comments later.
    
    Change-Id: I03bd48ca6e108e6253a77a137746165909ca3c3d

diff --git a/package/inc/ZipOutputEntry.hxx b/package/inc/ZipOutputEntry.hxx
index a1d03d3..73bd8a4 100644
--- a/package/inc/ZipOutputEntry.hxx
+++ b/package/inc/ZipOutputEntry.hxx
@@ -19,16 +19,17 @@
 #ifndef INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX
 #define INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX
 
+#include <com/sun/star/io/IOException.hpp>
 #include <com/sun/star/uno/Reference.hxx>
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <com/sun/star/xml/crypto/XCipherContext.hpp>
 #include <com/sun/star/xml/crypto/XDigestContext.hpp>
 
 #include <package/Deflater.hxx>
-#include <ByteChucker.hxx>
 #include <CRC32.hxx>
 
 struct ZipEntry;
+class ZipOutputStream;
 class ZipPackageStream;
 
 class ZipOutputEntry
@@ -40,7 +41,7 @@ class ZipOutputEntry
     ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XDigestContext > m_xDigestContext;
 
     CRC32               m_aCRC;
-    ByteChucker         &m_rChucker;
+    ZipOutputStream*    m_pZipOutputStream;
     ZipEntry            *m_pCurrentEntry;
     sal_Int16           m_nDigested;
     bool                m_bEncryptCurrentEntry;
@@ -49,29 +50,18 @@ class ZipOutputEntry
 public:
     ZipOutputEntry(
         const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
-        ByteChucker& rChucker, ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt = false);
+        ZipOutputStream *pZipOutputStream, ZipEntry& rEntry, ZipPackageStream* pStream, bool bEncrypt = false);
 
     ~ZipOutputEntry();
 
-    // rawWrite to support a direct write to the output stream
-    void SAL_CALL rawWrite( ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
-    void SAL_CALL rawCloseEntry(  )
-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
-
     // XZipOutputEntry interfaces
     void SAL_CALL closeEntry(  )
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
     void SAL_CALL write( const ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
-    static sal_uInt32 getCurrentDosTime ( );
 
 private:
     void doDeflate();
-    sal_Int32 writeLOC( const ZipEntry &rEntry )
-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
-    void writeEXT( const ZipEntry &rEntry )
-        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
 };
 
 #endif
diff --git a/package/inc/ZipOutputStream.hxx b/package/inc/ZipOutputStream.hxx
index 95c27f3..6775bd0 100644
--- a/package/inc/ZipOutputStream.hxx
+++ b/package/inc/ZipOutputStream.hxx
@@ -27,6 +27,7 @@
 #include <vector>
 
 struct ZipEntry;
+class ZipPackageStream;
 
 class ZipOutputStream
 {
@@ -35,22 +36,36 @@ class ZipOutputStream
 
     ByteChucker         m_aChucker;
     bool                m_bFinished;
+    ZipEntry            *m_pCurrentEntry;
 
 public:
     ZipOutputStream(
         const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > &xOStream );
     ~ZipOutputStream();
 
-    void addEntry( ZipEntry *pZipEntry );
+    // rawWrite to support a direct write to the output stream
+    void rawWrite( ::com::sun::star::uno::Sequence< sal_Int8 >& rBuffer, sal_Int32 nNewOffset, sal_Int32 nNewLength )
+        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+    void rawCloseEntry()
+        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+
+    void putNextEntry( ZipEntry& rEntry, bool bEncrypt = false )
+        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
     void finish()
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
     ByteChucker& getChucker();
 
+    static sal_uInt32 getCurrentDosTime();
+
 private:
     void writeEND(sal_uInt32 nOffset, sal_uInt32 nLength)
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
     void writeCEN( const ZipEntry &rEntry )
         throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+    sal_Int32 writeLOC( const ZipEntry &rEntry )
+        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+    void writeEXT( const ZipEntry &rEntry )
+        throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
 };
 
 #endif
diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx
index a3e3cc8..4e2f6d4 100644
--- a/package/source/zipapi/ZipOutputEntry.cxx
+++ b/package/source/zipapi/ZipOutputEntry.cxx
@@ -24,9 +24,11 @@
 
 #include <osl/time.h>
 
+#include <ByteChucker.hxx>
 #include <PackageConstants.hxx>
 #include <ZipEntry.hxx>
 #include <ZipFile.hxx>
+#include <ZipOutputStream.hxx>
 #include <ZipPackageStream.hxx>
 
 using namespace com::sun::star;
@@ -37,43 +39,24 @@ using namespace com::sun::star::packages::zip::ZipConstants;
 /** This class is used to deflate Zip entries
  */
 ZipOutputEntry::ZipOutputEntry( const uno::Reference< uno::XComponentContext >& rxContext,
-                        ByteChucker& rChucker,
+                        ZipOutputStream* pOutputStream,
                         ZipEntry& rEntry,
                         ZipPackageStream* pStream,
                         bool bEncrypt)
 : m_aDeflateBuffer(n_ConstBufferSize)
 , m_aDeflater(DEFAULT_COMPRESSION, true)
-, m_rChucker(rChucker)
+, m_pZipOutputStream(pOutputStream)
 , m_pCurrentEntry(&rEntry)
 , m_nDigested(0)
-, m_bEncryptCurrentEntry(false)
+, m_bEncryptCurrentEntry(bEncrypt)
 , m_pCurrentStream(NULL)
 {
-    if (rEntry.nTime == -1)
-        rEntry.nTime = getCurrentDosTime();
-    if (rEntry.nMethod == -1)
-        rEntry.nMethod = DEFLATED;
-    rEntry.nVersion = 20;
-    rEntry.nFlag = 1 << 11;
-    if (rEntry.nSize == -1 || rEntry.nCompressedSize == -1 ||
-        rEntry.nCrc == -1)
+    if (m_bEncryptCurrentEntry)
     {
-        rEntry.nSize = rEntry.nCompressedSize = 0;
-        rEntry.nFlag |= 8;
-    }
-
-    if (bEncrypt)
-    {
-        m_bEncryptCurrentEntry = true;
-
         m_xCipherContext = ZipFile::StaticGetCipher( rxContext, pStream->GetEncryptionData(), true );
         m_xDigestContext = ZipFile::StaticGetDigestContextForChecksum( rxContext, pStream->GetEncryptionData() );
-        m_nDigested = 0;
-        rEntry.nFlag |= 1 << 4;
         m_pCurrentStream = pStream;
     }
-    sal_Int32 nLOCLength = writeLOC(rEntry);
-    rEntry.nOffset = m_rChucker.GetPosition() - nLOCLength;
 }
 
 ZipOutputEntry::~ZipOutputEntry( void )
@@ -117,7 +100,6 @@ void SAL_CALL ZipOutputEntry::closeEntry(  )
                         pEntry->nCompressedSize = m_aDeflater.getTotalOut();
                     }
                     pEntry->nCrc = m_aCRC.getValue();
-                    writeEXT(*pEntry);
                 }
                 m_aDeflater.reset();
                 m_aCRC.reset();
@@ -170,27 +152,12 @@ void SAL_CALL ZipOutputEntry::write( const Sequence< sal_Int8 >& rBuffer, sal_In
         case STORED:
             {
                 Sequence < sal_Int8 > aTmpBuffer ( rBuffer.getConstArray(), nNewLength );
-                m_rChucker.WriteBytes( aTmpBuffer );
+                m_pZipOutputStream->getChucker().WriteBytes( aTmpBuffer );
             }
             break;
     }
 }
 
-void SAL_CALL ZipOutputEntry::rawWrite( Sequence< sal_Int8 >& rBuffer, sal_Int32 /*nNewOffset*/, sal_Int32 nNewLength )
-    throw(IOException, RuntimeException)
-{
-    Sequence < sal_Int8 > aTmpBuffer ( rBuffer.getConstArray(), nNewLength );
-    m_rChucker.WriteBytes( aTmpBuffer );
-}
-
-void SAL_CALL ZipOutputEntry::rawCloseEntry(  )
-    throw(IOException, RuntimeException)
-{
-    if ( m_pCurrentEntry->nMethod == DEFLATED && ( m_pCurrentEntry->nFlag & 8 ) )
-        writeEXT(*m_pCurrentEntry);
-    m_pCurrentEntry = NULL;
-}
-
 void ZipOutputEntry::doDeflate()
 {
     sal_Int32 nLength = m_aDeflater.doDeflateSegment(m_aDeflateBuffer, 0, m_aDeflateBuffer.getLength());
@@ -213,7 +180,7 @@ void ZipOutputEntry::doDeflate()
             // FIXME64: uno::Sequence not 64bit safe.
             uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->convertWithCipherContext( aTmpBuffer );
 
-            m_rChucker.WriteBytes( aEncryptionBuffer );
+            m_pZipOutputStream->getChucker().WriteBytes( aEncryptionBuffer );
 
             // the sizes as well as checksum for encrypted streams is calculated here
             m_pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength();
@@ -222,7 +189,7 @@ void ZipOutputEntry::doDeflate()
         }
         else
         {
-            m_rChucker.WriteBytes ( aTmpBuffer );
+            m_pZipOutputStream->getChucker().WriteBytes ( aTmpBuffer );
         }
     }
 
@@ -232,7 +199,7 @@ void ZipOutputEntry::doDeflate()
         uno::Sequence< sal_Int8 > aEncryptionBuffer = m_xCipherContext->finalizeCipherContextAndDispose();
         if ( aEncryptionBuffer.getLength() )
         {
-            m_rChucker.WriteBytes( aEncryptionBuffer );
+            m_pZipOutputStream->getChucker().WriteBytes( aEncryptionBuffer );
 
             // the sizes as well as checksum for encrypted streams is calculated hier
             m_pCurrentEntry->nCompressedSize += aEncryptionBuffer.getLength();
@@ -242,126 +209,4 @@ void ZipOutputEntry::doDeflate()
     }
 }
 
-static sal_uInt32 getTruncated( sal_Int64 nNum, bool *pIsTruncated )
-{
-    if( nNum >= 0xffffffff )
-    {
-        *pIsTruncated = true;
-        return 0xffffffff;
-    }
-    else
-        return static_cast< sal_uInt32 >( nNum );
-}
-
-void ZipOutputEntry::writeEXT( const ZipEntry &rEntry )
-    throw(IOException, RuntimeException)
-{
-    bool bWrite64Header = false;
-
-    m_rChucker << EXTSIG;
-    m_rChucker << static_cast < sal_uInt32> ( rEntry.nCrc );
-    m_rChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header );
-    m_rChucker << getTruncated( rEntry.nSize, &bWrite64Header );
-
-    if( bWrite64Header )
-    {
-        // FIXME64: need to append a ZIP64 header instead of throwing
-        // We're about to silently lose people's data - which they are
-        // unlikely to appreciate so fail instead:
-        throw IOException( "File contains streams that are too large." );
-    }
-}
-
-sal_Int32 ZipOutputEntry::writeLOC( const ZipEntry &rEntry )
-    throw(IOException, RuntimeException)
-{
-    if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( rEntry.sPath, true ) )
-        throw IOException("Unexpected character is used in file name." );
-
-    OString sUTF8Name = OUStringToOString( rEntry.sPath, RTL_TEXTENCODING_UTF8 );
-    sal_Int16 nNameLength       = static_cast < sal_Int16 > ( sUTF8Name.getLength() );
-
-    m_rChucker << LOCSIG;
-    m_rChucker << rEntry.nVersion;
-
-    if (rEntry.nFlag & (1 << 4) )
-    {
-        // If it's an encrypted entry, we pretend its stored plain text
-        sal_Int16 nTmpFlag = rEntry.nFlag;
-        nTmpFlag &= ~(1 <<4 );
-        m_rChucker << nTmpFlag;
-        m_rChucker << static_cast < sal_Int16 > ( STORED );
-    }
-    else
-    {
-        m_rChucker << rEntry.nFlag;
-        m_rChucker << rEntry.nMethod;
-    }
-
-    bool bWrite64Header = false;
-
-    m_rChucker << static_cast < sal_uInt32 > (rEntry.nTime);
-    if ((rEntry.nFlag & 8) == 8 )
-    {
-        m_rChucker << static_cast < sal_Int32 > (0);
-        m_rChucker << static_cast < sal_Int32 > (0);
-        m_rChucker << static_cast < sal_Int32 > (0);
-    }
-    else
-    {
-        m_rChucker << static_cast < sal_uInt32 > (rEntry.nCrc);
-        m_rChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header );
-        m_rChucker << getTruncated( rEntry.nSize, &bWrite64Header );
-    }
-    m_rChucker << nNameLength;
-    m_rChucker << static_cast < sal_Int16 > (0);
-
-    if( bWrite64Header )
-    {
-        // FIXME64: need to append a ZIP64 header instead of throwing
-        // We're about to silently lose people's data - which they are
-        // unlikely to appreciate so fail instead:
-        throw IOException( "File contains streams that are too large." );
-    }
-
-    Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() );
-    m_rChucker.WriteBytes( aSequence );
-
-    return LOCHDR + nNameLength;
-}
-sal_uInt32 ZipOutputEntry::getCurrentDosTime( )
-{
-    oslDateTime aDateTime;
-    TimeValue aTimeValue;
-    osl_getSystemTime ( &aTimeValue );
-    osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime);
-
-    // at year 2108, there is an overflow
-    // -> some decision needs to be made
-    // how to handle the ZIP file format (just overflow?)
-
-    // if the current system time is before 1980,
-    // then the time traveller will have to make a decision
-    // how to handle the ZIP file format before it is invented
-    // (just underflow?)
-
-    assert(aDateTime.Year > 1980 && aDateTime.Year < 2108);
-
-    sal_uInt32 nYear = static_cast <sal_uInt32> (aDateTime.Year);
-
-    if (nYear>=1980)
-        nYear-=1980;
-    else if (nYear>=80)
-    {
-        nYear-=80;
-    }
-    sal_uInt32 nResult = static_cast < sal_uInt32>( ( ( ( aDateTime.Day) +
-                                          ( 32 * (aDateTime.Month)) +
-                                          ( 512 * nYear ) ) << 16) |
-                                        ( ( aDateTime.Seconds/2) +
-                                            ( 32 * aDateTime.Minutes) +
-                                          ( 2048 * static_cast <sal_uInt32 > (aDateTime.Hours) ) ) );
-    return nResult;
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx
index 7cd5acd..29c19c4 100644
--- a/package/source/zipapi/ZipOutputStream.cxx
+++ b/package/source/zipapi/ZipOutputStream.cxx
@@ -23,8 +23,11 @@
 #include <com/sun/star/io/XOutputStream.hpp>
 #include <comphelper/storagehelper.hxx>
 
+#include <osl/time.h>
+
 #include <PackageConstants.hxx>
 #include <ZipEntry.hxx>
+#include <ZipPackageStream.hxx>
 
 using namespace com::sun::star;
 using namespace com::sun::star::io;
@@ -37,6 +40,7 @@ ZipOutputStream::ZipOutputStream( const uno::Reference < io::XOutputStream > &xO
 : m_xStream(xOStream)
 , m_aChucker(xOStream)
 , m_bFinished(false)
+, m_pCurrentEntry(NULL)
 {
 }
 
@@ -46,9 +50,45 @@ ZipOutputStream::~ZipOutputStream( void )
         delete m_aZipList[i];
 }
 
-void ZipOutputStream::addEntry( ZipEntry *pZipEntry )
+void ZipOutputStream::putNextEntry( ZipEntry& rEntry, bool bEncrypt )
+    throw(IOException, RuntimeException)
+{
+    assert(!m_pCurrentEntry && "Forgot to close an entry before putNextEntry()?");
+    if (rEntry.nTime == -1)
+        rEntry.nTime = getCurrentDosTime();
+    if (rEntry.nMethod == -1)
+        rEntry.nMethod = DEFLATED;
+    rEntry.nVersion = 20;
+    rEntry.nFlag = 1 << 11;
+    if (rEntry.nSize == -1 || rEntry.nCompressedSize == -1 ||
+        rEntry.nCrc == -1)
+    {
+        rEntry.nSize = rEntry.nCompressedSize = 0;
+        rEntry.nFlag |= 8;
+    }
+    if (bEncrypt)
+    {
+        rEntry.nFlag |= 1 << 4;
+    }
+
+    sal_Int32 nLOCLength = writeLOC(rEntry);
+    rEntry.nOffset = m_aChucker.GetPosition() - nLOCLength;
+    m_aZipList.push_back( &rEntry );
+    m_pCurrentEntry = &rEntry;
+}
+
+void ZipOutputStream::rawWrite( Sequence< sal_Int8 >& rBuffer, sal_Int32 /*nNewOffset*/, sal_Int32 nNewLength )
+    throw(IOException, RuntimeException)
+{
+    m_aChucker.WriteBytes( Sequence< sal_Int8 >(rBuffer.getConstArray(), nNewLength) );
+}
+
+void ZipOutputStream::rawCloseEntry()
+    throw(IOException, RuntimeException)
 {
-    m_aZipList.push_back( pZipEntry );
+    if ( m_pCurrentEntry->nMethod == DEFLATED && ( m_pCurrentEntry->nFlag & 8 ) )
+        writeEXT(*m_pCurrentEntry);
+    m_pCurrentEntry = NULL;
 }
 
 void ZipOutputStream::finish(  )
@@ -148,4 +188,116 @@ void ZipOutputStream::writeCEN( const ZipEntry &rEntry )
     m_aChucker.WriteBytes( aSequence );
 }
 
+void ZipOutputStream::writeEXT( const ZipEntry &rEntry )
+    throw(IOException, RuntimeException)
+{
+    bool bWrite64Header = false;
+
+    m_aChucker << EXTSIG;
+    m_aChucker << static_cast < sal_uInt32> ( rEntry.nCrc );
+    m_aChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header );
+    m_aChucker << getTruncated( rEntry.nSize, &bWrite64Header );
+
+    if( bWrite64Header )
+    {
+        // FIXME64: need to append a ZIP64 header instead of throwing
+        // We're about to silently lose people's data - which they are
+        // unlikely to appreciate so fail instead:
+        throw IOException( "File contains streams that are too large." );
+    }
+}
+
+sal_Int32 ZipOutputStream::writeLOC( const ZipEntry &rEntry )
+    throw(IOException, RuntimeException)
+{
+    if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( rEntry.sPath, true ) )
+        throw IOException("Unexpected character is used in file name." );
+
+    OString sUTF8Name = OUStringToOString( rEntry.sPath, RTL_TEXTENCODING_UTF8 );
+    sal_Int16 nNameLength       = static_cast < sal_Int16 > ( sUTF8Name.getLength() );
+
+    m_aChucker << LOCSIG;
+    m_aChucker << rEntry.nVersion;
+
+    if (rEntry.nFlag & (1 << 4) )
+    {
+        // If it's an encrypted entry, we pretend its stored plain text
+        sal_Int16 nTmpFlag = rEntry.nFlag;
+        nTmpFlag &= ~(1 <<4 );
+        m_aChucker << nTmpFlag;
+        m_aChucker << static_cast < sal_Int16 > ( STORED );
+    }
+    else
+    {
+        m_aChucker << rEntry.nFlag;
+        m_aChucker << rEntry.nMethod;
+    }
+
+    bool bWrite64Header = false;
+
+    m_aChucker << static_cast < sal_uInt32 > (rEntry.nTime);
+    if ((rEntry.nFlag & 8) == 8 )
+    {
+        m_aChucker << static_cast < sal_Int32 > (0);
+        m_aChucker << static_cast < sal_Int32 > (0);
+        m_aChucker << static_cast < sal_Int32 > (0);
+    }
+    else
+    {
+        m_aChucker << static_cast < sal_uInt32 > (rEntry.nCrc);
+        m_aChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header );
+        m_aChucker << getTruncated( rEntry.nSize, &bWrite64Header );
+    }
+    m_aChucker << nNameLength;
+    m_aChucker << static_cast < sal_Int16 > (0);
+
+    if( bWrite64Header )
+    {
+        // FIXME64: need to append a ZIP64 header instead of throwing
+        // We're about to silently lose people's data - which they are
+        // unlikely to appreciate so fail instead:
+        throw IOException( "File contains streams that are too large." );
+    }
+
+    Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() );
+    m_aChucker.WriteBytes( aSequence );
+
+    return LOCHDR + nNameLength;
+}
+
+sal_uInt32 ZipOutputStream::getCurrentDosTime()
+{
+    oslDateTime aDateTime;
+    TimeValue aTimeValue;
+    osl_getSystemTime ( &aTimeValue );
+    osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime);
+
+    // at year 2108, there is an overflow
+    // -> some decision needs to be made
+    // how to handle the ZIP file format (just overflow?)
+
+    // if the current system time is before 1980,
+    // then the time traveller will have to make a decision
+    // how to handle the ZIP file format before it is invented
+    // (just underflow?)
+
+    assert(aDateTime.Year > 1980 && aDateTime.Year < 2108);
+
+    sal_uInt32 nYear = static_cast <sal_uInt32> (aDateTime.Year);
+
+    if (nYear>=1980)
+        nYear-=1980;
+    else if (nYear>=80)
+    {
+        nYear-=80;
+    }
+    sal_uInt32 nResult = static_cast < sal_uInt32>( ( ( ( aDateTime.Day) +
+                                          ( 32 * (aDateTime.Month)) +
+                                          ( 512 * nYear ) ) << 16) |
+                                        ( ( aDateTime.Seconds/2) +
+                                            ( 32 * aDateTime.Minutes) +
+                                          ( 2048 * static_cast <sal_uInt32 > (aDateTime.Hours) ) ) );
+    return nResult;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
index 63fee5d..5c12cf0 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -976,7 +976,7 @@ void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut )
     pEntry->sPath = sMime;
     pEntry->nMethod = STORED;
     pEntry->nSize = pEntry->nCompressedSize = nBufferLength;
-    pEntry->nTime = ZipOutputEntry::getCurrentDosTime();
+    pEntry->nTime = ZipOutputStream::getCurrentDosTime();
 
     CRC32 aCRC32;
     aCRC32.update( aType );
@@ -984,10 +984,11 @@ void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut )
 
     try
     {
-        ZipOutputEntry aZipEntry(m_xContext, aZipOut.getChucker(), *pEntry, NULL);
+        aZipOut.putNextEntry(*pEntry);
+        ZipOutputEntry aZipEntry(m_xContext, &aZipOut, *pEntry, NULL);
         aZipEntry.write(aType, 0, nBufferLength);
         aZipEntry.closeEntry();
-        aZipOut.addEntry(pEntry);
+        aZipOut.rawCloseEntry();
     }
     catch ( const ::com::sun::star::io::IOException & r )
     {
@@ -1010,7 +1011,7 @@ void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< uno::Seq
     pEntry->nMethod = DEFLATED;
     pEntry->nCrc = -1;
     pEntry->nSize = pEntry->nCompressedSize = -1;
-    pEntry->nTime = ZipOutputEntry::getCurrentDosTime();
+    pEntry->nTime = ZipOutputStream::getCurrentDosTime();
 
     // Convert vector into a uno::Sequence
     uno::Sequence < uno::Sequence < PropertyValue > > aManifestSequence ( aManList.size() );
@@ -1027,10 +1028,11 @@ void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< uno::Seq
     pBuffer->realloc( nBufferLength );
 
     // the manifest.xml is never encrypted - so pass an empty reference
-    ZipOutputEntry aZipEntry(m_xContext, aZipOut.getChucker(), *pEntry, NULL);
+    aZipOut.putNextEntry(*pEntry);
+    ZipOutputEntry aZipEntry(m_xContext, &aZipOut, *pEntry, NULL);
     aZipEntry.write(pBuffer->getSequence(), 0, nBufferLength);
     aZipEntry.closeEntry();
-    aZipOut.addEntry(pEntry);
+    aZipOut.rawCloseEntry();
 }
 
 void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno::Sequence < PropertyValue > >& aManList )
@@ -1043,7 +1045,7 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno:
     pEntry->nMethod = DEFLATED;
     pEntry->nCrc = -1;
     pEntry->nSize = pEntry->nCompressedSize = -1;
-    pEntry->nTime = ZipOutputEntry::getCurrentDosTime();
+    pEntry->nTime = ZipOutputStream::getCurrentDosTime();
 
     // Convert vector into a uno::Sequence
     // TODO/LATER: use Defaulst entries in future
@@ -1078,10 +1080,11 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno:
     pBuffer->realloc( nBufferLength );
 
     // there is no encryption in this format currently
-    ZipOutputEntry aZipEntry(m_xContext, aZipOut.getChucker(), *pEntry, NULL);
+    aZipOut.putNextEntry(*pEntry);
+    ZipOutputEntry aZipEntry(m_xContext, &aZipOut, *pEntry, NULL);
     aZipEntry.write(pBuffer->getSequence(), 0, nBufferLength);
     aZipEntry.closeEntry();
-    aZipOut.addEntry(pEntry);
+    aZipOut.rawCloseEntry();
 }
 
 void ZipPackage::ConnectTo( const uno::Reference< io::XInputStream >& xInStream )
diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx
index c2e5a4f..a6b2e5c 100644
--- a/package/source/zippackage/ZipPackageFolder.cxx
+++ b/package/source/zippackage/ZipPackageFolder.cxx
@@ -21,7 +21,6 @@
 
 #include <ZipPackageFolder.hxx>
 #include <ZipFile.hxx>
-#include <ZipOutputEntry.hxx>
 #include <ZipOutputStream.hxx>
 #include <ZipPackageStream.hxx>
 #include <PackageConstants.hxx>
@@ -338,9 +337,8 @@ void ZipPackageFolder::saveContents(
 
         try
         {
-            ZipOutputEntry aZipEntry(m_xContext, rZipOut.getChucker(), *pTempEntry, NULL, false);
-            aZipEntry.rawCloseEntry();
-            rZipOut.addEntry(pTempEntry);
+            rZipOut.putNextEntry( *pTempEntry );
+            rZipOut.rawCloseEntry();
         }
         catch ( ZipException& )
         {
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index 4ff73ce..8d433ad 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -674,7 +674,7 @@ bool ZipPackageStream::saveChild(
             if ( bRawStream )
                 xStream->skipBytes( m_nMagicalHackPos );
 
-            ZipOutputEntry aZipEntry(m_xContext, rZipOut.getChucker(), *pTempEntry, this, false);
+            rZipOut.putNextEntry(*pTempEntry);
             // the entry is provided to the ZipOutputStream that will delete it
             pAutoTempEntry.release();
 
@@ -684,12 +684,11 @@ bool ZipPackageStream::saveChild(
             do
             {
                 nLength = xStream->readBytes( aSeq, n_ConstBufferSize );
-                aZipEntry.rawWrite(aSeq, 0, nLength);
+                rZipOut.rawWrite(aSeq, 0, nLength);
             }
             while ( nLength == n_ConstBufferSize );
 
-            aZipEntry.rawCloseEntry();
-            rZipOut.addEntry(pTempEntry);
+            rZipOut.rawCloseEntry();
         }
         catch ( ZipException& )
         {
@@ -732,7 +731,8 @@ bool ZipPackageStream::saveChild(
 
         try
         {
-            ZipOutputEntry aZipEntry(m_xContext, rZipOut.getChucker(), *pTempEntry, this, bToBeEncrypted);
+            rZipOut.putNextEntry(*pTempEntry, bToBeEncrypted);
+            ZipOutputEntry aZipEntry(m_xContext, &rZipOut, *pTempEntry, this, bToBeEncrypted);
             // the entry is provided to the ZipOutputStream that will delete it
             pAutoTempEntry.release();
 
@@ -746,7 +746,7 @@ bool ZipPackageStream::saveChild(
             while ( nLength == n_ConstBufferSize );
 
             aZipEntry.closeEntry();
-            rZipOut.addEntry(pTempEntry);
+            rZipOut.rawCloseEntry();
         }
         catch ( ZipException& )
         {
commit 902dfbd18f5fc38847390cf2faae00172c7f733c
Author: Matúš Kukan <matus.kukan at collabora.com>
Date:   Mon Oct 20 12:34:42 2014 +0200

    ZipPackageFolder: releaseUpwardRef only calls clearParent, remove it.
    
    Since commit 0c5bb3f42d38b3c16015dc0a45defd1b1dad4f92.
    
    Change-Id: I5511f9dc829aca42790f05cb8fb3ebd83b2acad4

diff --git a/package/inc/ZipPackageFolder.hxx b/package/inc/ZipPackageFolder.hxx
index 52a64e6..1f4e84db 100644
--- a/package/inc/ZipPackageFolder.hxx
+++ b/package/inc/ZipPackageFolder.hxx
@@ -82,7 +82,6 @@ public:
             const com::sun::star::uno::Sequence< sal_Int8 > &rEncryptionKey,
             const rtlRandomPool & rRandomPool) const
         throw(::com::sun::star::uno::RuntimeException);
-    void  releaseUpwardRef();
 
     // XNameContainer
     virtual void SAL_CALL insertByName( const OUString& aName, const ::com::sun::star::uno::Any& aElement )
diff --git a/package/source/zippackage/ContentInfo.hxx b/package/source/zippackage/ContentInfo.hxx
index 1911999..4b66395 100644
--- a/package/source/zippackage/ContentInfo.hxx
+++ b/package/source/zippackage/ContentInfo.hxx
@@ -50,7 +50,7 @@ public:
     virtual ~ContentInfo ()
     {
         if ( bFolder )
-            pFolder->releaseUpwardRef();
+            pFolder->clearParent();
         else
             pStream->clearParent();
     }
diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx
index 4420fdc..c2e5a4f 100644
--- a/package/source/zippackage/ZipPackageFolder.cxx
+++ b/package/source/zippackage/ZipPackageFolder.cxx
@@ -392,35 +392,6 @@ void ZipPackageFolder::saveContents(
         throw uno::RuntimeException(THROW_WHERE );
 }
 
-void ZipPackageFolder::releaseUpwardRef( void )
-{
-    // Now it is possible that a package folder is disconnected from the package before removing of the folder.
-    // Such a scenario is used in storage implementation. When a new version of a folder is provided the old
-    // one is retrieved, removed from the package but preserved for the error handling.
-    // In this scenario the referencing to the parent is not really useful, since it requires disposing.
-
-    // Actually there is no need in having a reference to the parent, it even make things more complicated and
-    // requires disposing mechanics. Using of a simple pointer seems to be easier solution and also a safe enough.
-
-    clearParent();
-
-#if 0
-    for ( ContentHash::const_iterator aCI = maContents.begin();
-          aCI!=maContents.end();
-          aCI++)
-    {
-        ContentInfo &rInfo = * (*aCI).second;
-        if ( rInfo.bFolder )// && ! rInfo.pFolder->HasReleased () )
-            rInfo.pFolder->releaseUpwardRef();
-        else //if ( !rInfo.bFolder && !rInfo.pStream->HasReleased() )
-            rInfo.pStream->clearParent();
-    }
-    clearParent();
-
-    OSL_ENSURE ( m_refCount == 1, "Ref-count is not 1!" );
-#endif
-}
-
 sal_Int64 SAL_CALL ZipPackageFolder::getSomething( const uno::Sequence< sal_Int8 >& aIdentifier )
     throw(uno::RuntimeException, std::exception)
 {


More information about the Libreoffice-commits mailing list