summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
authorMatúš Kukan <matus.kukan@collabora.com>2014-10-07 16:04:13 +0200
committerMatúš Kukan <matus.kukan@collabora.com>2014-10-10 13:50:03 +0200
commit9f495d128e9e1cc05b2e1f56f11f1ac4055d738d (patch)
tree9b869c3d20779a133ccd1fe1e13910685164781c /package
parent04ebf437087c0a849dacf4816f0f2ee45799f840 (diff)
Split ZipPackageFolder::saveChild into two functions
And make them static. Probably would be better to kill ContentInfo and add saveChild as pure virtual into ZipPackageEntry, from which are both ZipPackageFolder and ZipPackageStream inheriting. This will also create a bit more sensible call graph when profiling. Change-Id: If8151332cfa6359e8736c912b7a5633a9162ab36
Diffstat (limited to 'package')
-rw-r--r--package/inc/ZipPackageFolder.hxx9
-rw-r--r--package/source/zippackage/ZipPackageFolder.cxx621
2 files changed, 340 insertions, 290 deletions
diff --git a/package/inc/ZipPackageFolder.hxx b/package/inc/ZipPackageFolder.hxx
index 81eddd7b069c..6053b48d844e 100644
--- a/package/inc/ZipPackageFolder.hxx
+++ b/package/inc/ZipPackageFolder.hxx
@@ -79,10 +79,13 @@ public:
void setPackageFormat_Impl( sal_Int32 nFormat ) { m_nFormat = nFormat; }
void setRemoveOnInsertMode_Impl( bool bRemove ) { this->mbAllowRemoveOnInsert = bRemove; }
- bool saveChild(const OUString &rShortName, const com::sun::star::packages::ContentInfo &rInfo, OUString &rPath, std::vector < com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, const com::sun::star::uno::Sequence < sal_Int8 >& rEncryptionKey, rtlRandomPool & rRandomPool) const;
-
// Recursive functions
- void saveContents(OUString &rPath, std::vector < com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > > &rManList, ZipOutputStream & rZipOut, const com::sun::star::uno::Sequence< sal_Int8 > &rEncryptionKey, rtlRandomPool & rRandomPool) const
+ void saveContents(
+ const OUString &rPath,
+ std::vector < com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue > > &rManList,
+ ZipOutputStream & rZipOut,
+ const com::sun::star::uno::Sequence< sal_Int8 > &rEncryptionKey,
+ const rtlRandomPool & rRandomPool) const
throw(::com::sun::star::uno::RuntimeException);
void releaseUpwardRef();
diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx
index 9855dc172406..c0baf907bbf6 100644
--- a/package/source/zippackage/ZipPackageFolder.cxx
+++ b/package/source/zippackage/ZipPackageFolder.cxx
@@ -294,7 +294,57 @@ static void ImplSetStoredData( ZipEntry & rEntry, uno::Reference< XInputStream>
rEntry.nCrc = aCRC32.getValue();
}
-bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo &rInfo, OUString &rPath, std::vector < uno::Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, const uno::Sequence < sal_Int8 >& rEncryptionKey, rtlRandomPool &rRandomPool) const
+static bool ZipPackageFolder_saveChild(
+ const ContentInfo &rInfo,
+ const OUString &rPath,
+ std::vector < uno::Sequence < PropertyValue > > &rManList,
+ ZipOutputStream & rZipOut,
+ const uno::Sequence < sal_Int8 >& rEncryptionKey,
+ const rtlRandomPool &rRandomPool,
+ sal_Int32 nFormat)
+{
+ bool bSuccess = true;
+
+ const OUString sMediaTypeProperty ("MediaType");
+ const OUString sVersionProperty ("Version");
+ const OUString sFullPathProperty ("FullPath");
+
+ uno::Sequence < PropertyValue > aPropSet (PKG_SIZE_NOENCR_MNFST);
+
+ assert( rInfo.bFolder && rInfo.pFolder && "A valid child object is expected!" );
+
+ OUString sTempName = rPath + "/";
+
+ if ( !rInfo.pFolder->GetMediaType().isEmpty() )
+ {
+ aPropSet[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty;
+ aPropSet[PKG_MNFST_MEDIATYPE].Value <<= rInfo.pFolder->GetMediaType();
+ aPropSet[PKG_MNFST_VERSION].Name = sVersionProperty;
+ aPropSet[PKG_MNFST_VERSION].Value <<= rInfo.pFolder->GetVersion();
+ aPropSet[PKG_MNFST_FULLPATH].Name = sFullPathProperty;
+ aPropSet[PKG_MNFST_FULLPATH].Value <<= sTempName;
+ }
+ else
+ aPropSet.realloc( 0 );
+
+ rInfo.pFolder->saveContents( sTempName, rManList, rZipOut, rEncryptionKey, rRandomPool);
+
+ // folder can have a mediatype only in package format
+ if ( aPropSet.getLength()
+ && ( nFormat == embed::StorageFormats::PACKAGE || ( nFormat == embed::StorageFormats::OFOPXML && !rInfo.bFolder ) ) )
+ rManList.push_back( aPropSet );
+
+ return bSuccess;
+}
+
+static bool ZipPackageStream_saveChild(
+ const ContentInfo &rInfo,
+ const OUString &rPath,
+ std::vector < uno::Sequence < PropertyValue > > &rManList,
+ ZipOutputStream & rZipOut,
+ const uno::Sequence < sal_Int8 >& rEncryptionKey,
+ const rtlRandomPool &rRandomPool,
+ sal_Int32 nFormat)
{
bool bSuccess = true;
@@ -309,311 +359,165 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
const OUString sEncryptionAlgProperty ("EncryptionAlgorithm");
const OUString sStartKeyAlgProperty ("StartKeyAlgorithm");
const OUString sDigestAlgProperty ("DigestAlgorithm");
- const OUString sDerivedKeySizeProperty ("DerivedKeySize");
+ const OUString sDerivedKeySizeProperty ("DerivedKeySize");
uno::Sequence < PropertyValue > aPropSet (PKG_SIZE_NOENCR_MNFST);
- OSL_ENSURE( ( rInfo.bFolder && rInfo.pFolder ) || ( !rInfo.bFolder && rInfo.pStream ), "A valid child object is expected!" );
- if ( rInfo.bFolder )
- {
- OUString sTempName = rPath + rShortName + "/";
+ assert( !rInfo.bFolder && rInfo.pStream && "A valid child object is expected!" );
- if ( !rInfo.pFolder->GetMediaType().isEmpty() )
- {
- aPropSet[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty;
- aPropSet[PKG_MNFST_MEDIATYPE].Value <<= rInfo.pFolder->GetMediaType();
- aPropSet[PKG_MNFST_VERSION].Name = sVersionProperty;
- aPropSet[PKG_MNFST_VERSION].Value <<= rInfo.pFolder->GetVersion();
- aPropSet[PKG_MNFST_FULLPATH].Name = sFullPathProperty;
- aPropSet[PKG_MNFST_FULLPATH].Value <<= sTempName;
- }
- else
- aPropSet.realloc( 0 );
+ // if pTempEntry is necessary, it will be released and passed to the ZipOutputStream
+ // and be deleted in the ZipOutputStream destructor
+ unique_ptr < ZipEntry > pAutoTempEntry ( new ZipEntry );
+ ZipEntry* pTempEntry = pAutoTempEntry.get();
- rInfo.pFolder->saveContents( sTempName, rManList, rZipOut, rEncryptionKey, rRandomPool);
- }
- else
- {
- // if pTempEntry is necessary, it will be released and passed to the ZipOutputStream
- // and be deleted in the ZipOutputStream destructor
- unique_ptr < ZipEntry > pAutoTempEntry ( new ZipEntry );
- ZipEntry* pTempEntry = pAutoTempEntry.get();
+ // In case the entry we are reading is also the entry we are writing, we will
+ // store the ZipEntry data in pTempEntry
- // In case the entry we are reading is also the entry we are writing, we will
- // store the ZipEntry data in pTempEntry
+ ZipPackageFolder::copyZipEntry ( *pTempEntry, rInfo.pStream->aEntry );
+ pTempEntry->sPath = rPath;
+ pTempEntry->nPathLen = (sal_Int16)( OUStringToOString( pTempEntry->sPath, RTL_TEXTENCODING_UTF8 ).getLength() );
- ZipPackageFolder::copyZipEntry ( *pTempEntry, rInfo.pStream->aEntry );
- pTempEntry->sPath = rPath + rShortName;
- pTempEntry->nPathLen = (sal_Int16)( OUStringToOString( pTempEntry->sPath, RTL_TEXTENCODING_UTF8 ).getLength() );
+ bool bToBeEncrypted = rInfo.pStream->IsToBeEncrypted() && (rEncryptionKey.getLength() || rInfo.pStream->HasOwnKey());
+ bool bToBeCompressed = bToBeEncrypted ? sal_True : rInfo.pStream->IsToBeCompressed();
- bool bToBeEncrypted = rInfo.pStream->IsToBeEncrypted() && (rEncryptionKey.getLength() || rInfo.pStream->HasOwnKey());
- bool bToBeCompressed = bToBeEncrypted ? sal_True : rInfo.pStream->IsToBeCompressed();
+ aPropSet[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty;
+ aPropSet[PKG_MNFST_MEDIATYPE].Value <<= rInfo.pStream->GetMediaType( );
+ aPropSet[PKG_MNFST_VERSION].Name = sVersionProperty;
+ aPropSet[PKG_MNFST_VERSION].Value <<= OUString(); // no version is stored for streams currently
+ aPropSet[PKG_MNFST_FULLPATH].Name = sFullPathProperty;
+ aPropSet[PKG_MNFST_FULLPATH].Value <<= pTempEntry->sPath;
- aPropSet[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty;
- aPropSet[PKG_MNFST_MEDIATYPE].Value <<= rInfo.pStream->GetMediaType( );
- aPropSet[PKG_MNFST_VERSION].Name = sVersionProperty;
- aPropSet[PKG_MNFST_VERSION].Value <<= OUString(); // no version is stored for streams currently
- aPropSet[PKG_MNFST_FULLPATH].Name = sFullPathProperty;
- aPropSet[PKG_MNFST_FULLPATH].Value <<= pTempEntry->sPath;
+ OSL_ENSURE( rInfo.pStream->GetStreamMode() != PACKAGE_STREAM_NOTSET, "Unacceptable ZipPackageStream mode!" );
- OSL_ENSURE( rInfo.pStream->GetStreamMode() != PACKAGE_STREAM_NOTSET, "Unacceptable ZipPackageStream mode!" );
+ bool bRawStream = false;
+ if ( rInfo.pStream->GetStreamMode() == PACKAGE_STREAM_DETECT )
+ bRawStream = rInfo.pStream->ParsePackageRawStream();
+ else if ( rInfo.pStream->GetStreamMode() == PACKAGE_STREAM_RAW )
+ bRawStream = true;
- bool bRawStream = false;
- if ( rInfo.pStream->GetStreamMode() == PACKAGE_STREAM_DETECT )
- bRawStream = rInfo.pStream->ParsePackageRawStream();
- else if ( rInfo.pStream->GetStreamMode() == PACKAGE_STREAM_RAW )
- bRawStream = true;
+ 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 ? rInfo.pStream->GetMagicalHackSize() : rInfo.pStream->getSize();
- 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 ? rInfo.pStream->GetMagicalHackSize() : rInfo.pStream->getSize();
+ bool bUseNonSeekableAccess = false;
+ uno::Reference < XInputStream > xStream;
+ if ( !rInfo.pStream->IsPackageMember() && !bRawStream && !bToBeEncrypted && bToBeCompressed )
+ {
+ // the stream is not a package member, not a raw stream,
+ // it should not be encrypted and it should be compressed,
+ // in this case nonseekable access can be used
- bool bUseNonSeekableAccess = false;
- uno::Reference < XInputStream > xStream;
- if ( !rInfo.pStream->IsPackageMember() && !bRawStream && !bToBeEncrypted && bToBeCompressed )
- {
- // the stream is not a package member, not a raw stream,
- // it should not be encrypted and it should be compressed,
- // in this case nonseekable access can be used
+ xStream = rInfo.pStream->GetOwnStreamNoWrap();
+ uno::Reference < XSeekable > xSeek ( xStream, uno::UNO_QUERY );
- xStream = rInfo.pStream->GetOwnStreamNoWrap();
- uno::Reference < XSeekable > xSeek ( xStream, uno::UNO_QUERY );
+ bUseNonSeekableAccess = ( xStream.is() && !xSeek.is() );
+ }
- bUseNonSeekableAccess = ( xStream.is() && !xSeek.is() );
- }
+ if ( !bUseNonSeekableAccess )
+ {
+ xStream = rInfo.pStream->getRawData();
- if ( !bUseNonSeekableAccess )
+ if ( !xStream.is() )
{
- xStream = rInfo.pStream->getRawData();
-
- if ( !xStream.is() )
- {
- OSL_FAIL( "ZipPackageStream didn't have a stream associated with it, skipping!" );
- bSuccess = false;
- return bSuccess;
- }
+ OSL_FAIL( "ZipPackageStream didn't have a stream associated with it, skipping!" );
+ bSuccess = false;
+ return bSuccess;
+ }
- uno::Reference < XSeekable > xSeek ( xStream, uno::UNO_QUERY );
- try
+ uno::Reference < XSeekable > xSeek ( xStream, uno::UNO_QUERY );
+ try
+ {
+ if ( xSeek.is() )
{
- if ( xSeek.is() )
+ // If the stream is a raw one, then we should be positioned
+ // at the beginning of the actual data
+ if ( !bToBeCompressed || bRawStream )
{
- // If the stream is a raw one, then we should be positioned
- // at the beginning of the actual data
- if ( !bToBeCompressed || bRawStream )
- {
- // The raw stream can neither be encrypted nor connected
- OSL_ENSURE( !bRawStream || !(bToBeCompressed || bToBeEncrypted), "The stream is already encrypted!\n" );
- xSeek->seek ( bRawStream ? rInfo.pStream->GetMagicalHackPos() : 0 );
- ImplSetStoredData ( *pTempEntry, xStream );
-
- // TODO/LATER: Get rid of hacks related to switching of Flag Method and Size properties!
- }
- else if ( bToBeEncrypted )
- {
- // this is the correct original size
- pTempEntry->nSize = xSeek->getLength();
- nOwnStreamOrigSize = pTempEntry->nSize;
- }
+ // The raw stream can neither be encrypted nor connected
+ OSL_ENSURE( !bRawStream || !(bToBeCompressed || bToBeEncrypted), "The stream is already encrypted!\n" );
+ xSeek->seek ( bRawStream ? rInfo.pStream->GetMagicalHackPos() : 0 );
+ ImplSetStoredData ( *pTempEntry, xStream );
- xSeek->seek ( 0 );
+ // TODO/LATER: Get rid of hacks related to switching of Flag Method and Size properties!
}
- else
+ else if ( bToBeEncrypted )
{
- // Okay, we don't have an xSeekable stream. This is possibly bad.
- // check if it's one of our own streams, if it is then we know that
- // each time we ask for it we'll get a new stream that will be
- // at position zero...otherwise, assert and skip this stream...
- if ( rInfo.pStream->IsPackageMember() )
- {
- // if the password has been changed than the stream should not be package member any more
- if ( rInfo.pStream->IsEncrypted() && rInfo.pStream->IsToBeEncrypted() )
- {
- // Should be handled close to the raw stream handling
- bTransportOwnEncrStreamAsRaw = true;
- pTempEntry->nMethod = STORED;
-
- // TODO/LATER: get rid of this situation
- // this size should be different from the one that will be stored in manifest.xml
- // it is used in storing algorithms and after storing the correct size will be set
- pTempEntry->nSize = pTempEntry->nCompressedSize;
- }
- }
- else
- {
- bSuccess = false;
- return bSuccess;
- }
+ // this is the correct original size
+ pTempEntry->nSize = xSeek->getLength();
+ nOwnStreamOrigSize = pTempEntry->nSize;
}
- }
- catch ( uno::Exception& )
- {
- bSuccess = false;
- return bSuccess;
- }
- if ( bToBeEncrypted || bRawStream || bTransportOwnEncrStreamAsRaw )
+ xSeek->seek ( 0 );
+ }
+ else
{
- if ( bToBeEncrypted && !bTransportOwnEncrStreamAsRaw )
+ // Okay, we don't have an xSeekable stream. This is possibly bad.
+ // check if it's one of our own streams, if it is then we know that
+ // each time we ask for it we'll get a new stream that will be
+ // at position zero...otherwise, assert and skip this stream...
+ if ( rInfo.pStream->IsPackageMember() )
{
- uno::Sequence < sal_Int8 > aSalt( 16 ), aVector( rInfo.pStream->GetBlockSize() );
- rtl_random_getBytes ( rRandomPool, aSalt.getArray(), 16 );
- rtl_random_getBytes ( rRandomPool, aVector.getArray(), aVector.getLength() );
- sal_Int32 nIterationCount = 1024;
-
- if ( !rInfo.pStream->HasOwnKey() )
- rInfo.pStream->setKey ( rEncryptionKey );
-
- rInfo.pStream->setInitialisationVector ( aVector );
- rInfo.pStream->setSalt ( aSalt );
- rInfo.pStream->setIterationCount ( nIterationCount );
- }
-
- // last property is digest, which is inserted later if we didn't have
- // a magic header
- aPropSet.realloc(PKG_SIZE_ENCR_MNFST);
-
- aPropSet[PKG_MNFST_INIVECTOR].Name = sInitialisationVectorProperty;
- aPropSet[PKG_MNFST_INIVECTOR].Value <<= rInfo.pStream->getInitialisationVector();
- aPropSet[PKG_MNFST_SALT].Name = sSaltProperty;
- aPropSet[PKG_MNFST_SALT].Value <<= rInfo.pStream->getSalt();
- aPropSet[PKG_MNFST_ITERATION].Name = sIterationCountProperty;
- aPropSet[PKG_MNFST_ITERATION].Value <<= rInfo.pStream->getIterationCount ();
-
- // Need to store the uncompressed size in the manifest
- OSL_ENSURE( nOwnStreamOrigSize >= 0, "The stream size was not correctly initialized!\n" );
- aPropSet[PKG_MNFST_UCOMPSIZE].Name = sSizeProperty;
- aPropSet[PKG_MNFST_UCOMPSIZE].Value <<= nOwnStreamOrigSize;
-
- if ( bRawStream || bTransportOwnEncrStreamAsRaw )
- {
- ::rtl::Reference< EncryptionData > xEncData = rInfo.pStream->GetEncryptionData();
- if ( !xEncData.is() )
- throw uno::RuntimeException();
-
- aPropSet[PKG_MNFST_DIGEST].Name = sDigestProperty;
- aPropSet[PKG_MNFST_DIGEST].Value <<= rInfo.pStream->getDigest();
- aPropSet[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
- aPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg;
- aPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
- aPropSet[PKG_MNFST_STARTALG].Value <<= xEncData->m_nStartKeyGenID;
- aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
- aPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg;
- aPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
- aPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize;
+ // if the password has been changed than the stream should not be package member any more
+ if ( rInfo.pStream->IsEncrypted() && rInfo.pStream->IsToBeEncrypted() )
+ {
+ // Should be handled close to the raw stream handling
+ bTransportOwnEncrStreamAsRaw = true;
+ pTempEntry->nMethod = STORED;
+
+ // TODO/LATER: get rid of this situation
+ // this size should be different from the one that will be stored in manifest.xml
+ // it is used in storing algorithms and after storing the correct size will be set
+ pTempEntry->nSize = pTempEntry->nCompressedSize;
+ }
}
- }
- }
-
- // 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
- || ( rInfo.pStream->IsPackageMember() && !bToBeEncrypted
- && ( ( rInfo.pStream->aEntry.nMethod == DEFLATED && bToBeCompressed )
- || ( rInfo.pStream->aEntry.nMethod == STORED && !bToBeCompressed ) ) ) ) )
- {
- // If it's a PackageMember, then it's an unbuffered stream and we need
- // to get a new version of it as we can't seek backwards.
- if ( rInfo.pStream->IsPackageMember() )
- {
- xStream = rInfo.pStream->getRawData();
- if ( !xStream.is() )
+ else
{
- // Make sure that we actually _got_ a new one !
bSuccess = false;
return bSuccess;
}
}
-
- try
- {
- if ( bRawStream )
- xStream->skipBytes( rInfo.pStream->GetMagicalHackPos() );
-
- rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, false );
- // the entry is provided to the ZipOutputStream that will delete it
- pAutoTempEntry.release();
-
- uno::Sequence < sal_Int8 > aSeq ( n_ConstBufferSize );
- sal_Int32 nLength;
-
- do
- {
- nLength = xStream->readBytes( aSeq, n_ConstBufferSize );
- rZipOut.rawWrite(aSeq, 0, nLength);
- }
- while ( nLength == n_ConstBufferSize );
-
- rZipOut.rawCloseEntry();
- }
- catch ( ZipException& )
- {
- bSuccess = false;
- }
- catch ( IOException& )
- {
- bSuccess = false;
- }
}
- else
+ catch ( uno::Exception& )
{
- // This stream is defenitly not a raw stream
-
- // If nonseekable access is used the stream should be at the beginning and
- // is useless after the storing. Thus if the storing fails the package should
- // be thrown away ( as actually it is done currently )!
- // To allow to reuse the package after the error, the optimization must be removed!
+ bSuccess = false;
+ return bSuccess;
+ }
- // If it's a PackageMember, then our previous reference held a 'raw' stream
- // so we need to re-get it, unencrypted, uncompressed and positioned at the
- // beginning of the stream
- if ( rInfo.pStream->IsPackageMember() )
+ if ( bToBeEncrypted || bRawStream || bTransportOwnEncrStreamAsRaw )
+ {
+ if ( bToBeEncrypted && !bTransportOwnEncrStreamAsRaw )
{
- xStream = rInfo.pStream->getInputStream();
- if ( !xStream.is() )
- {
- // Make sure that we actually _got_ a new one !
- bSuccess = false;
- return bSuccess;
- }
- }
+ uno::Sequence < sal_Int8 > aSalt( 16 ), aVector( rInfo.pStream->GetBlockSize() );
+ rtl_random_getBytes ( rRandomPool, aSalt.getArray(), 16 );
+ rtl_random_getBytes ( rRandomPool, aVector.getArray(), aVector.getLength() );
+ sal_Int32 nIterationCount = 1024;
- if ( bToBeCompressed )
- {
- pTempEntry->nMethod = DEFLATED;
- pTempEntry->nCrc = -1;
- pTempEntry->nCompressedSize = pTempEntry->nSize = -1;
+ if ( !rInfo.pStream->HasOwnKey() )
+ rInfo.pStream->setKey ( rEncryptionKey );
+
+ rInfo.pStream->setInitialisationVector ( aVector );
+ rInfo.pStream->setSalt ( aSalt );
+ rInfo.pStream->setIterationCount ( nIterationCount );
}
- try
- {
- rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, bToBeEncrypted);
- // the entry is provided to the ZipOutputStream that will delete it
- pAutoTempEntry.release();
+ // last property is digest, which is inserted later if we didn't have
+ // a magic header
+ aPropSet.realloc(PKG_SIZE_ENCR_MNFST);
- sal_Int32 nLength;
- uno::Sequence < sal_Int8 > aSeq (n_ConstBufferSize);
- do
- {
- nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
- rZipOut.write(aSeq, 0, nLength);
- }
- while ( nLength == n_ConstBufferSize );
+ aPropSet[PKG_MNFST_INIVECTOR].Name = sInitialisationVectorProperty;
+ aPropSet[PKG_MNFST_INIVECTOR].Value <<= rInfo.pStream->getInitialisationVector();
+ aPropSet[PKG_MNFST_SALT].Name = sSaltProperty;
+ aPropSet[PKG_MNFST_SALT].Value <<= rInfo.pStream->getSalt();
+ aPropSet[PKG_MNFST_ITERATION].Name = sIterationCountProperty;
+ aPropSet[PKG_MNFST_ITERATION].Value <<= rInfo.pStream->getIterationCount ();
- rZipOut.closeEntry();
- }
- catch ( ZipException& )
- {
- bSuccess = false;
- }
- catch ( IOException& )
- {
- bSuccess = false;
- }
+ // Need to store the uncompressed size in the manifest
+ OSL_ENSURE( nOwnStreamOrigSize >= 0, "The stream size was not correctly initialized!\n" );
+ aPropSet[PKG_MNFST_UCOMPSIZE].Name = sSizeProperty;
+ aPropSet[PKG_MNFST_UCOMPSIZE].Value <<= nOwnStreamOrigSize;
- if ( bToBeEncrypted )
+ if ( bRawStream || bTransportOwnEncrStreamAsRaw )
{
::rtl::Reference< EncryptionData > xEncData = rInfo.pStream->GetEncryptionData();
if ( !xEncData.is() )
@@ -629,53 +533,184 @@ bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo
aPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg;
aPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
aPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize;
-
- rInfo.pStream->SetIsEncrypted ( true );
}
}
+ }
- if( bSuccess )
+ // 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
+ || ( rInfo.pStream->IsPackageMember() && !bToBeEncrypted
+ && ( ( rInfo.pStream->aEntry.nMethod == DEFLATED && bToBeCompressed )
+ || ( rInfo.pStream->aEntry.nMethod == STORED && !bToBeCompressed ) ) ) ) )
+ {
+ // If it's a PackageMember, then it's an unbuffered stream and we need
+ // to get a new version of it as we can't seek backwards.
+ if ( rInfo.pStream->IsPackageMember() )
{
- if ( !rInfo.pStream->IsPackageMember() )
+ xStream = rInfo.pStream->getRawData();
+ if ( !xStream.is() )
{
- rInfo.pStream->CloseOwnStreamIfAny();
- rInfo.pStream->SetPackageMember ( true );
+ // Make sure that we actually _got_ a new one !
+ bSuccess = false;
+ return bSuccess;
}
+ }
+ try
+ {
if ( bRawStream )
+ xStream->skipBytes( rInfo.pStream->GetMagicalHackPos() );
+
+ rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, false );
+ // the entry is provided to the ZipOutputStream that will delete it
+ pAutoTempEntry.release();
+
+ uno::Sequence < sal_Int8 > aSeq ( n_ConstBufferSize );
+ sal_Int32 nLength;
+
+ do
+ {
+ nLength = xStream->readBytes( aSeq, n_ConstBufferSize );
+ rZipOut.rawWrite(aSeq, 0, nLength);
+ }
+ while ( nLength == n_ConstBufferSize );
+
+ rZipOut.rawCloseEntry();
+ }
+ catch ( ZipException& )
+ {
+ bSuccess = false;
+ }
+ catch ( IOException& )
+ {
+ bSuccess = false;
+ }
+ }
+ else
+ {
+ // This stream is defenitly not a raw stream
+
+ // If nonseekable access is used the stream should be at the beginning and
+ // is useless after the storing. Thus if the storing fails the package should
+ // be thrown away ( as actually it is done currently )!
+ // To allow to reuse the package after the error, the optimization must be removed!
+
+ // If it's a PackageMember, then our previous reference held a 'raw' stream
+ // so we need to re-get it, unencrypted, uncompressed and positioned at the
+ // beginning of the stream
+ if ( rInfo.pStream->IsPackageMember() )
+ {
+ xStream = rInfo.pStream->getInputStream();
+ if ( !xStream.is() )
{
- // the raw stream was integrated and now behaves
- // as usual encrypted stream
- rInfo.pStream->SetToBeEncrypted( true );
+ // Make sure that we actually _got_ a new one !
+ bSuccess = false;
+ return bSuccess;
}
+ }
+
+ if ( bToBeCompressed )
+ {
+ pTempEntry->nMethod = DEFLATED;
+ pTempEntry->nCrc = -1;
+ pTempEntry->nCompressedSize = pTempEntry->nSize = -1;
+ }
- // Then copy it back afterwards...
- ZipPackageFolder::copyZipEntry ( rInfo.pStream->aEntry, *pTempEntry );
+ try
+ {
+ rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, bToBeEncrypted);
+ // the entry is provided to the ZipOutputStream that will delete it
+ pAutoTempEntry.release();
- // Remove hacky bit from entry flags
- if ( rInfo.pStream->aEntry.nFlag & ( 1 << 4 ) )
+ sal_Int32 nLength;
+ uno::Sequence < sal_Int8 > aSeq (n_ConstBufferSize);
+ do
{
- rInfo.pStream->aEntry.nFlag &= ~( 1 << 4 );
- rInfo.pStream->aEntry.nMethod = STORED;
+ nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
+ rZipOut.write(aSeq, 0, nLength);
}
+ while ( nLength == n_ConstBufferSize );
- // TODO/LATER: get rid of this hack ( the encrypted stream size property is changed during saving )
- if ( rInfo.pStream->IsEncrypted() )
- rInfo.pStream->setSize( nOwnStreamOrigSize );
+ rZipOut.closeEntry();
+ }
+ catch ( ZipException& )
+ {
+ bSuccess = false;
+ }
+ catch ( IOException& )
+ {
+ bSuccess = false;
+ }
- rInfo.pStream->aEntry.nOffset *= -1;
+ if ( bToBeEncrypted )
+ {
+ ::rtl::Reference< EncryptionData > xEncData = rInfo.pStream->GetEncryptionData();
+ if ( !xEncData.is() )
+ throw uno::RuntimeException();
+
+ aPropSet[PKG_MNFST_DIGEST].Name = sDigestProperty;
+ aPropSet[PKG_MNFST_DIGEST].Value <<= rInfo.pStream->getDigest();
+ aPropSet[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
+ aPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg;
+ aPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
+ aPropSet[PKG_MNFST_STARTALG].Value <<= xEncData->m_nStartKeyGenID;
+ aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
+ aPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg;
+ aPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
+ aPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize;
+
+ rInfo.pStream->SetIsEncrypted ( true );
}
}
+ if( bSuccess )
+ {
+ if ( !rInfo.pStream->IsPackageMember() )
+ {
+ rInfo.pStream->CloseOwnStreamIfAny();
+ rInfo.pStream->SetPackageMember ( true );
+ }
+
+ if ( bRawStream )
+ {
+ // the raw stream was integrated and now behaves
+ // as usual encrypted stream
+ rInfo.pStream->SetToBeEncrypted( true );
+ }
+
+ // Then copy it back afterwards...
+ ZipPackageFolder::copyZipEntry ( rInfo.pStream->aEntry, *pTempEntry );
+
+ // Remove hacky bit from entry flags
+ if ( rInfo.pStream->aEntry.nFlag & ( 1 << 4 ) )
+ {
+ rInfo.pStream->aEntry.nFlag &= ~( 1 << 4 );
+ rInfo.pStream->aEntry.nMethod = STORED;
+ }
+
+ // TODO/LATER: get rid of this hack ( the encrypted stream size property is changed during saving )
+ if ( rInfo.pStream->IsEncrypted() )
+ rInfo.pStream->setSize( nOwnStreamOrigSize );
+
+ rInfo.pStream->aEntry.nOffset *= -1;
+ }
+
// folder can have a mediatype only in package format
if ( aPropSet.getLength()
- && ( m_nFormat == embed::StorageFormats::PACKAGE || ( m_nFormat == embed::StorageFormats::OFOPXML && !rInfo.bFolder ) ) )
+ && ( nFormat == embed::StorageFormats::PACKAGE || ( nFormat == embed::StorageFormats::OFOPXML && !rInfo.bFolder ) ) )
rManList.push_back( aPropSet );
return bSuccess;
}
-void ZipPackageFolder::saveContents( OUString &rPath, std::vector < uno::Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, const uno::Sequence < sal_Int8 >& rEncryptionKey, rtlRandomPool &rRandomPool ) const
+void ZipPackageFolder::saveContents(
+ const OUString &rPath,
+ std::vector < uno::Sequence < PropertyValue > > &rManList,
+ ZipOutputStream & rZipOut,
+ const uno::Sequence < sal_Int8 >& rEncryptionKey,
+ const rtlRandomPool &rRandomPool ) const
throw( uno::RuntimeException )
{
bool bWritingFailed = false;
@@ -708,12 +743,13 @@ void ZipPackageFolder::saveContents( OUString &rPath, std::vector < uno::Sequenc
OUString aMimeTypeStreamName("mimetype");
if ( m_nFormat == embed::StorageFormats::ZIP && rPath.isEmpty() )
{
- // let the "mimtype" stream in root folder be stored as the first stream if it is zip format
+ // let the "mimetype" stream in root folder be stored as the first stream if it is zip format
ContentHash::const_iterator aIter = maContents.find ( aMimeTypeStreamName );
if ( aIter != maContents.end() && !(*aIter).second->bFolder )
{
bMimeTypeStreamStored = true;
- bWritingFailed = !saveChild( (*aIter).first, *(*aIter).second, rPath, rManList, rZipOut, rEncryptionKey, rRandomPool );
+ bWritingFailed = !ZipPackageStream_saveChild(
+ *aIter->second, rPath + aIter->first, rManList, rZipOut, rEncryptionKey, rRandomPool, m_nFormat );
}
}
@@ -725,7 +761,18 @@ void ZipPackageFolder::saveContents( OUString &rPath, std::vector < uno::Sequenc
const ContentInfo &rInfo = *(*aCI).second;
if ( !bMimeTypeStreamStored || !rShortName.equals( aMimeTypeStreamName ) )
- bWritingFailed = !saveChild( rShortName, rInfo, rPath, rManList, rZipOut, rEncryptionKey, rRandomPool );
+ {
+ if (rInfo.bFolder)
+ {
+ bWritingFailed = !ZipPackageFolder_saveChild(
+ rInfo, rPath + rShortName, rManList, rZipOut, rEncryptionKey, rRandomPool, m_nFormat );
+ }
+ else
+ {
+ bWritingFailed = !ZipPackageStream_saveChild(
+ rInfo, rPath + rShortName, rManList, rZipOut, rEncryptionKey, rRandomPool, m_nFormat );
+ }
+ }
}
if( bWritingFailed )