Kaydet (Commit) ca13a937 authored tarafından Matúš Kukan's avatar Matúš Kukan Kaydeden (comit) Jan Holesovsky

package: Add ZipOutputEntry to isolate deflating of streams.

Preparation commit for deflating streams in parallel.
We still use the same single XOutputStream (ByteChucker :-) for
sequential writing but this can now be changed more easily.

Change-Id: Idf26cc2187461660e31ac2e12c4708e761596fb2
üst 827879a0
......@@ -55,6 +55,7 @@ $(eval $(call gb_Library_add_exception_objects,package2,\
package/source/zipapi/XUnbufferedStream \
package/source/zipapi/ZipEnumeration \
package/source/zipapi/ZipFile \
package/source/zipapi/ZipOutputEntry \
package/source/zipapi/ZipOutputStream \
package/source/zippackage/wrapstreamforshare \
package/source/zippackage/zipfileaccess \
......
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX
#define INCLUDED_PACKAGE_INC_ZIPOUTPUTENTRY_HXX
#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 ZipPackageStream;
class ZipOutputEntry
{
::com::sun::star::uno::Sequence< sal_Int8 > m_aDeflateBuffer;
ZipUtils::Deflater m_aDeflater;
::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;
ByteChucker &m_rChucker;
ZipEntry *m_pCurrentEntry;
sal_Int16 m_nDigested;
bool m_bEncryptCurrentEntry;
ZipPackageStream* m_pCurrentStream;
public:
ZipOutputEntry(
const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
ByteChucker& rChucker, 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
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -21,75 +21,36 @@
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/io/XOutputStream.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>
#include <vector>
struct ZipEntry;
class ZipPackageStream;
class ZipOutputStream
{
protected:
::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext> m_xContext;
::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > m_xStream;
::std::vector < ZipEntry * > m_aZipList;
::com::sun::star::uno::Sequence< sal_Int8 > m_aDeflateBuffer;
OUString m_sComment;
ZipUtils::Deflater m_aDeflater;
::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;
ByteChucker m_aChucker;
ZipEntry *m_pCurrentEntry;
sal_Int16 m_nDigested;
bool m_bFinished, m_bEncryptCurrentEntry;
ZipPackageStream* m_pCurrentStream;
bool m_bFinished;
public:
ZipOutputStream(
const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > &xOStream );
~ZipOutputStream();
// 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( )
void addEntry( ZipEntry *pZipEntry );
void finish()
throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
ByteChucker& getChucker();
// XZipOutputStream interfaces
void SAL_CALL putNextEntry( ZipEntry& rEntry,
ZipPackageStream* pStream,
bool bEncrypt = false )
throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
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 SAL_CALL finish( )
throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
static sal_uInt32 getCurrentDosTime ( );
protected:
void doDeflate();
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);
void writeEXT( 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);
};
#endif
......
......@@ -22,6 +22,7 @@
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/beans/StringPair.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <HashMaps.hxx>
#include <ZipPackageEntry.hxx>
#include <cppuhelper/implbase2.hxx>
......@@ -50,13 +51,15 @@ class ZipPackageFolder : public cppu::ImplInheritanceHelper2
>
{
private:
css::uno::Reference< css::uno::XComponentContext> m_xContext;
ContentHash maContents;
sal_Int32 m_nFormat;
OUString m_sVersion;
public:
ZipPackageFolder( sal_Int32 nFormat,
ZipPackageFolder( css::uno::Reference< css::uno::XComponentContext> xContext,
sal_Int32 nFormat,
bool bAllowRemoveOnInsert );
virtual ~ZipPackageFolder();
......
This diff is collapsed.
......@@ -22,6 +22,7 @@
#include <ZipEnumeration.hxx>
#include <ZipPackageStream.hxx>
#include <ZipPackageFolder.hxx>
#include <ZipOutputEntry.hxx>
#include <ZipOutputStream.hxx>
#include <ZipPackageBuffer.hxx>
#include <ZipFile.hxx>
......@@ -156,7 +157,7 @@ ZipPackage::ZipPackage ( const uno::Reference < XComponentContext > &xContext )
, m_pRootFolder( NULL )
, m_pZipFile( NULL )
{
m_xRootFolder = m_pRootFolder = new ZipPackageFolder( m_nFormat, m_bAllowRemoveOnInsert );
m_xRootFolder = m_pRootFolder = new ZipPackageFolder( m_xContext, m_nFormat, m_bAllowRemoveOnInsert );
}
ZipPackage::~ZipPackage( void )
......@@ -539,7 +540,7 @@ void ZipPackage::getZipFileContents()
break;
if ( !pCurrent->hasByName( sTemp ) )
{
pPkgFolder = new ZipPackageFolder( m_nFormat, m_bAllowRemoveOnInsert );
pPkgFolder = new ZipPackageFolder( m_xContext, m_nFormat, m_bAllowRemoveOnInsert );
pPkgFolder->setName( sTemp );
pPkgFolder->doSetParent( pCurrent, true );
pCurrent = pPkgFolder;
......@@ -953,7 +954,7 @@ uno::Reference< XInterface > SAL_CALL ZipPackage::createInstanceWithArguments( c
if ( aArguments.getLength() )
aArguments[0] >>= bArg;
if ( bArg )
xRef = *new ZipPackageFolder ( m_nFormat, m_bAllowRemoveOnInsert );
xRef = *new ZipPackageFolder ( m_xContext, m_nFormat, m_bAllowRemoveOnInsert );
else
xRef = *new ZipPackageStream ( *this, m_xContext, m_bAllowRemoveOnInsert );
......@@ -975,7 +976,7 @@ void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut )
pEntry->sPath = sMime;
pEntry->nMethod = STORED;
pEntry->nSize = pEntry->nCompressedSize = nBufferLength;
pEntry->nTime = ZipOutputStream::getCurrentDosTime();
pEntry->nTime = ZipOutputEntry::getCurrentDosTime();
CRC32 aCRC32;
aCRC32.update( aType );
......@@ -983,9 +984,10 @@ void ZipPackage::WriteMimetypeMagicFile( ZipOutputStream& aZipOut )
try
{
aZipOut.putNextEntry( *pEntry, NULL );
aZipOut.write( aType, 0, nBufferLength );
aZipOut.closeEntry();
ZipOutputEntry aZipEntry(m_xContext, aZipOut.getChucker(), *pEntry, NULL);
aZipEntry.write(aType, 0, nBufferLength);
aZipEntry.closeEntry();
aZipOut.addEntry(pEntry);
}
catch ( const ::com::sun::star::io::IOException & r )
{
......@@ -1008,7 +1010,7 @@ void ZipPackage::WriteManifest( ZipOutputStream& aZipOut, const vector< uno::Seq
pEntry->nMethod = DEFLATED;
pEntry->nCrc = -1;
pEntry->nSize = pEntry->nCompressedSize = -1;
pEntry->nTime = ZipOutputStream::getCurrentDosTime();
pEntry->nTime = ZipOutputEntry::getCurrentDosTime();
// Convert vector into a uno::Sequence
uno::Sequence < uno::Sequence < PropertyValue > > aManifestSequence ( aManList.size() );
......@@ -1025,9 +1027,10 @@ 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, NULL );
aZipOut.write( pBuffer->getSequence(), 0, nBufferLength );
aZipOut.closeEntry();
ZipOutputEntry aZipEntry(m_xContext, aZipOut.getChucker(), *pEntry, NULL);
aZipEntry.write(pBuffer->getSequence(), 0, nBufferLength);
aZipEntry.closeEntry();
aZipOut.addEntry(pEntry);
}
void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno::Sequence < PropertyValue > >& aManList )
......@@ -1040,7 +1043,7 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno:
pEntry->nMethod = DEFLATED;
pEntry->nCrc = -1;
pEntry->nSize = pEntry->nCompressedSize = -1;
pEntry->nTime = ZipOutputStream::getCurrentDosTime();
pEntry->nTime = ZipOutputEntry::getCurrentDosTime();
// Convert vector into a uno::Sequence
// TODO/LATER: use Defaulst entries in future
......@@ -1075,9 +1078,10 @@ void ZipPackage::WriteContentTypes( ZipOutputStream& aZipOut, const vector< uno:
pBuffer->realloc( nBufferLength );
// there is no encryption in this format currently
aZipOut.putNextEntry( *pEntry, NULL );
aZipOut.write( pBuffer->getSequence(), 0, nBufferLength );
aZipOut.closeEntry();
ZipOutputEntry aZipEntry(m_xContext, aZipOut.getChucker(), *pEntry, NULL);
aZipEntry.write(pBuffer->getSequence(), 0, nBufferLength);
aZipEntry.closeEntry();
aZipOut.addEntry(pEntry);
}
void ZipPackage::ConnectTo( const uno::Reference< io::XInputStream >& xInStream )
......@@ -1138,7 +1142,7 @@ uno::Reference< io::XInputStream > ZipPackage::writeTempFile()
}
// Hand it to the ZipOutputStream:
ZipOutputStream aZipOut( m_xContext, xTempOut );
ZipOutputStream aZipOut( xTempOut );
try
{
if ( m_nFormat == embed::StorageFormats::PACKAGE )
......
......@@ -21,6 +21,7 @@
#include <ZipPackageFolder.hxx>
#include <ZipFile.hxx>
#include <ZipOutputEntry.hxx>
#include <ZipOutputStream.hxx>
#include <ZipPackageStream.hxx>
#include <PackageConstants.hxx>
......@@ -60,9 +61,11 @@ using namespace ::com::sun::star;
namespace { struct lcl_CachedImplId : public rtl::Static< cppu::OImplementationId, lcl_CachedImplId > {}; }
ZipPackageFolder::ZipPackageFolder ( sal_Int32 nFormat,
ZipPackageFolder::ZipPackageFolder ( css::uno::Reference< css::uno::XComponentContext> xContext,
sal_Int32 nFormat,
bool bAllowRemoveOnInsert )
: m_nFormat( nFormat )
: m_xContext( xContext )
, m_nFormat( nFormat )
{
this->mbAllowRemoveOnInsert = bAllowRemoveOnInsert;
......@@ -338,6 +341,7 @@ static bool ZipPackageFolder_saveChild(
}
static bool ZipPackageStream_saveChild(
css::uno::Reference< css::uno::XComponentContext> xContext,
const ContentInfo &rInfo,
const OUString &rPath,
std::vector < uno::Sequence < PropertyValue > > &rManList,
......@@ -563,7 +567,7 @@ static bool ZipPackageStream_saveChild(
if ( bRawStream )
xStream->skipBytes( rInfo.pStream->GetMagicalHackPos() );
rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, false );
ZipOutputEntry aZipEntry(xContext, rZipOut.getChucker(), *pTempEntry, rInfo.pStream, false);
// the entry is provided to the ZipOutputStream that will delete it
pAutoTempEntry.release();
......@@ -573,11 +577,12 @@ static bool ZipPackageStream_saveChild(
do
{
nLength = xStream->readBytes( aSeq, n_ConstBufferSize );
rZipOut.rawWrite(aSeq, 0, nLength);
aZipEntry.rawWrite(aSeq, 0, nLength);
}
while ( nLength == n_ConstBufferSize );
rZipOut.rawCloseEntry();
aZipEntry.rawCloseEntry();
rZipOut.addEntry(pTempEntry);
}
catch ( ZipException& )
{
......@@ -620,7 +625,7 @@ static bool ZipPackageStream_saveChild(
try
{
rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, bToBeEncrypted);
ZipOutputEntry aZipEntry(xContext, rZipOut.getChucker(), *pTempEntry, rInfo.pStream, bToBeEncrypted);
// the entry is provided to the ZipOutputStream that will delete it
pAutoTempEntry.release();
......@@ -629,11 +634,12 @@ static bool ZipPackageStream_saveChild(
do
{
nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
rZipOut.write(aSeq, 0, nLength);
aZipEntry.write(aSeq, 0, nLength);
}
while ( nLength == n_ConstBufferSize );
rZipOut.closeEntry();
aZipEntry.closeEntry();
rZipOut.addEntry(pTempEntry);
}
catch ( ZipException& )
{
......@@ -726,8 +732,9 @@ void ZipPackageFolder::saveContents(
try
{
rZipOut.putNextEntry( *pTempEntry, NULL, false );
rZipOut.rawCloseEntry();
ZipOutputEntry aZipEntry(m_xContext, rZipOut.getChucker(), *pTempEntry, NULL, false);
aZipEntry.rawCloseEntry();
rZipOut.addEntry(pTempEntry);
}
catch ( ZipException& )
{
......@@ -748,7 +755,7 @@ void ZipPackageFolder::saveContents(
if ( aIter != maContents.end() && !(*aIter).second->bFolder )
{
bMimeTypeStreamStored = true;
bWritingFailed = !ZipPackageStream_saveChild(
bWritingFailed = !ZipPackageStream_saveChild( m_xContext,
*aIter->second, rPath + aIter->first, rManList, rZipOut, rEncryptionKey, rRandomPool, m_nFormat );
}
}
......@@ -769,7 +776,7 @@ void ZipPackageFolder::saveContents(
}
else
{
bWritingFailed = !ZipPackageStream_saveChild(
bWritingFailed = !ZipPackageStream_saveChild( m_xContext,
rInfo, rPath + rShortName, rManList, rZipOut, rEncryptionKey, rRandomPool, m_nFormat );
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment