summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
authorMartin Gallwey <mtg@openoffice.org>2001-12-04 16:53:19 +0000
committerMartin Gallwey <mtg@openoffice.org>2001-12-04 16:53:19 +0000
commit90ddd03b58649e19dea12fb21de59e996f073965 (patch)
treee6c7cfc59d2698633bcad46e34d43482efa04294 /package
parentecd83d3387e72bb6c5203670bb0171e4635c6a6b (diff)
#95155# support for unbuffered streams
Diffstat (limited to 'package')
-rw-r--r--package/inc/CRC32.hxx7
-rw-r--r--package/source/zipapi/CRC32.cxx31
-rw-r--r--package/source/zippackage/ZipPackageFolder.cxx105
3 files changed, 78 insertions, 65 deletions
diff --git a/package/inc/CRC32.hxx b/package/inc/CRC32.hxx
index 549f24129d6b..63efd28a7e90 100644
--- a/package/inc/CRC32.hxx
+++ b/package/inc/CRC32.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: CRC32.hxx,v $
*
- * $Revision: 1.9 $
+ * $Revision: 1.10 $
*
- * last change: $Author: mtg $ $Date: 2001-11-15 19:51:16 $
+ * last change: $Author: mtg $ $Date: 2001-12-04 17:49:25 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -78,7 +78,8 @@ protected:
public:
CRC32();
~CRC32();
- void SAL_CALL updateStream (::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > & xStream)
+
+ sal_Int32 SAL_CALL updateStream (::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > & xStream)
throw(::com::sun::star::uno::RuntimeException);
void SAL_CALL updateByte (sal_Int8 nByte)
throw(::com::sun::star::uno::RuntimeException);
diff --git a/package/source/zipapi/CRC32.cxx b/package/source/zipapi/CRC32.cxx
index a8e356a1a65c..b892b8e40811 100644
--- a/package/source/zipapi/CRC32.cxx
+++ b/package/source/zipapi/CRC32.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: CRC32.cxx,v $
*
- * $Revision: 1.8 $
+ * $Revision: 1.9 $
*
- * last change: $Author: mtg $ $Date: 2001-11-15 20:13:09 $
+ * last change: $Author: mtg $ $Date: 2001-12-04 17:48:19 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -59,7 +59,7 @@
*
************************************************************************/
#ifndef _CRC32_HXX
-#include "CRC32.hxx"
+#include <CRC32.hxx>
#endif
#ifndef _ZLIB_H
#include <external/zlib/zlib.h>
@@ -67,9 +67,6 @@
#ifndef _PACKAGE_CONSTANTS_HXX_
#include <PackageConstants.hxx>
#endif
-#ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_
-#include <com/sun/star/io/XSeekable.hpp>
-#endif
#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif
@@ -124,20 +121,18 @@ void SAL_CALL CRC32::update(const Sequence< sal_Int8 > &b)
nCRC = crc32(nCRC, (const unsigned char*)b.getConstArray(),b.getLength());
}
-void SAL_CALL CRC32::updateStream( Reference < XInputStream > & xStream )
+sal_Int32 SAL_CALL CRC32::updateStream( Reference < XInputStream > & xStream )
throw ( RuntimeException )
{
- Reference < XSeekable > xSeek ( xStream, UNO_QUERY );
- if ( xSeek.is() )
+ sal_Int32 nLength, nTotal = 0;
+ Sequence < sal_Int8 > aSeq ( n_ConstBufferSize );
+ do
{
- sal_Int32 nLength = n_ConstBufferSize;
- sal_Int64 nCurrentPos = xSeek->getPosition();
- Sequence < sal_Int8 > aSeq ( n_ConstBufferSize );
- while ( nLength >= n_ConstBufferSize )
- {
- nLength = xStream->readBytes ( aSeq, n_ConstBufferSize );
- updateSegment ( aSeq, 0, nLength );
- }
- xSeek->seek ( nCurrentPos );
+ nLength = xStream->readBytes ( aSeq, n_ConstBufferSize );
+ updateSegment ( aSeq, 0, nLength );
+ nTotal += nLength;
}
+ while ( nLength == n_ConstBufferSize );
+
+ return nTotal;
}
diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx
index 8eb5d699848d..e8cd3a888b47 100644
--- a/package/source/zippackage/ZipPackageFolder.cxx
+++ b/package/source/zippackage/ZipPackageFolder.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: ZipPackageFolder.cxx,v $
*
- * $Revision: 1.55 $
+ * $Revision: 1.56 $
*
- * last change: $Author: mtg $ $Date: 2001-11-15 20:34:48 $
+ * last change: $Author: mtg $ $Date: 2001-12-04 17:53:19 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -103,6 +103,7 @@
#ifndef _RTL_RANDOM_H_
#include <rtl/random.h>
#endif
+#include <memory>
using namespace com::sun::star::packages::zip::ZipConstants;
using namespace com::sun::star::packages::zip;
@@ -253,17 +254,16 @@ void SAL_CALL ZipPackageFolder::replaceByName( const OUString& aName, const Any&
insertByName(aName, aElement);
}
-static void ImplSetStoredData( ZipEntry * pEntry, sal_Int32 nLength, Reference < XInputStream> & rStream )
+static void ImplSetStoredData( ZipEntry & rEntry, Reference < XInputStream> & rStream )
{
// It's very annoying that we have to do this, but lots of zip packages
// don't allow data descriptors for STORED streams, meaning we have to
// know the size and CRC32 of uncompressed streams before we actually
// write them !
CRC32 aCRC32;
- pEntry->nMethod = STORED;
- pEntry->nCompressedSize = pEntry->nSize = nLength;
- aCRC32.updateStream ( rStream );
- pEntry->nCrc = aCRC32.getValue();
+ rEntry.nMethod = STORED;
+ rEntry.nCompressedSize = rEntry.nSize = aCRC32.updateStream ( rStream );
+ rEntry.nCrc = aCRC32.getValue();
}
void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, Sequence < sal_Int8 > &rEncryptionKey, rtlRandomPool &rRandomPool)
@@ -309,9 +309,9 @@ void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < Pr
}
else
{
- // pTempEntry is stored in a vector by ZipOutputStream and will
- // be deleted by the ZipOutputStream destructor
- ZipEntry * pTempEntry = new ZipEntry;
+ // if pTempEntry is necessary, it will be released and passed to the ZipOutputStream
+ // and be deleted in the ZipOutputStream destructor
+ auto_ptr < ZipEntry > pTempEntry ( new ZipEntry );
// In case the entry we are reading is also the entry we are writing, we will
// store the ZipEntry data in pTempEntry
@@ -328,16 +328,9 @@ void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < Pr
pValue[1].Value <<= pTempEntry->sName;
Reference < XInputStream > xStream;
- Reference < XSeekable > xSeek;
-
sal_Int32 nMagicalHackPos = 0, nMagicalHackSize = 0;
{
xStream = pStream->getRawStream();
- xSeek = Reference < XSeekable > ( xStream, UNO_QUERY );
- // should probably do more than assert if we don't have an XSeekable interface...
- VOS_ENSURE ( xSeek.is(), "Bad juju! We can only package streams which support XSeekable!");
-
- xSeek->seek ( 0 );
Sequence < sal_Int8 > aHeader ( 4 );
if ( xStream->readBytes ( aHeader, 4 ) == 4 )
@@ -353,20 +346,46 @@ void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < Pr
pStream->SetToBeEncrypted ( sal_True );
pStream->SetIsEncrypted ( sal_True );
ZipFile::StaticFillData ( pStream->getEncryptionData(), nMagicalHackSize, xStream );
- // the stream will currently be positioned after the header, so
- // remember this position for copying
- nMagicalHackPos = static_cast < sal_Int32 > ( xSeek->getPosition() );
+ // We'll want to skip the data we've just read, so calculate how much we just read
+ // and remember it
+ nMagicalHackPos = n_ConstHeaderSize + pStream->getSalt().getLength()
+ + pStream->getInitialisationVector().getLength()
+ + pStream->getDigest().getLength ();
// it's already compressed and encrypted
bToBeEncrypted = bToBeCompressed = sal_False;
}
}
- if ( !nMagicalHackPos )
- xSeek->seek ( 0 );
}
- sal_Int32 nStreamLength = static_cast < sal_Int32 > ( xSeek->getLength() ) - nMagicalHackPos;
+ Reference < XSeekable > xSeek ( xStream, UNO_QUERY );
+ if ( xSeek.is() )
+ {
+ // If nMagicalHackPos is not zero, then we should be positioned
+ // at the beginning of the actual data
+ if ( !bToBeCompressed || nMagicalHackPos )
+ {
+ if ( !nMagicalHackPos )
+ xSeek->seek ( 0 );
+ ImplSetStoredData ( *pTempEntry, xStream );
+ }
+ else if ( bToBeEncrypted )
+ pTempEntry->nSize = static_cast < sal_Int32 > ( xSeek->getLength() );
+ xSeek->seek ( 0 );
+ }
+ else
+ {
+ // 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 ( !pStream->IsPackageMember() )
+ {
+ VOS_ENSURE( 0, "The package component requires that every stream either be FROM a package or it must support XSeekable!" );
+ continue;
+ }
+ }
- if ( bToBeEncrypted || nMagicalHackPos )
+ if ( bToBeEncrypted || nMagicalHackPos )
{
if ( bToBeEncrypted )
{
@@ -401,8 +420,10 @@ void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < Pr
pValue[3].Value <<= pStream->getSalt();
pValue[4].Name = sIterationCountProperty;
pValue[4].Value <<= pStream->getIterationCount ();
+
+ // Need to store the uncompressed size in the manifest
pValue[5].Name = sSizeProperty;
- pValue[5].Value <<= nMagicalHackSize ? nMagicalHackSize : nStreamLength;
+ pValue[5].Value <<= nMagicalHackPos ? nMagicalHackSize : pTempEntry->nSize;
if ( nMagicalHackPos )
{
@@ -418,23 +439,27 @@ void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < Pr
( pStream->aEntry.nMethod == DEFLATED && bToBeCompressed ) ||
( pStream->aEntry.nMethod == STORED && !bToBeCompressed ) ) )
{
+ // clear previous reference and get a new one that points to the beginning
+ // of the raw stream (we can't be sure that the stream will support
+ // XSeekable)
+ xStream = pStream->getRawStream();
try
{
if ( nMagicalHackPos )
- {
- xSeek->seek ( nMagicalHackPos );
- ImplSetStoredData ( pTempEntry, nStreamLength, xStream );
- }
- rZipOut.putNextEntry ( *pTempEntry, pStream->getEncryptionData(), sal_False );
+ xStream->skipBytes( nMagicalHackPos );
+
+ rZipOut.putNextEntry ( *(pTempEntry.get()), pStream->getEncryptionData(), sal_False );
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 );
+ while ( nLength == n_ConstBufferSize );
+
rZipOut.rawCloseEntry();
}
catch (ZipException&)
@@ -448,31 +473,22 @@ void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < Pr
}
else
{
-
// clear previous reference and replace it with the real stream
xStream = pStream->getInputStream();
- xSeek = Reference < XSeekable > ( xStream, UNO_QUERY );
-
- // should probably do more than assert if we don't have an XSeekable interface...
- VOS_ENSURE ( xSeek.is(), "Bad juju! We can only package streams which support XSeekable!");
-
// skip the magic header when generating the CRC and writing the stream
if ( nMagicalHackPos )
- xSeek->seek ( nMagicalHackPos );
+ xStream->skipBytes ( nMagicalHackPos );
if ( bToBeCompressed )
{
pTempEntry->nMethod = DEFLATED;
pTempEntry->nCrc = pTempEntry->nCompressedSize = pTempEntry->nSize = -1;
}
- else
- ImplSetStoredData ( pTempEntry, nStreamLength, xStream );
-
try
{
- rZipOut.putNextEntry ( *pTempEntry, pStream->getEncryptionData(), bToBeEncrypted);
+ rZipOut.putNextEntry ( *(pTempEntry.get()), pStream->getEncryptionData(), bToBeEncrypted);
sal_Int32 nLength;
Sequence < sal_Int8 > aSeq (n_ConstBufferSize);
do
@@ -480,7 +496,7 @@ void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < Pr
nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
rZipOut.write(aSeq, 0, nLength);
}
- while ( nLength >= n_ConstBufferSize );
+ while ( nLength == n_ConstBufferSize );
pStream->SetPackageMember ( sal_True );
rZipOut.closeEntry();
}
@@ -494,7 +510,6 @@ void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < Pr
}
if ( bToBeEncrypted && !nMagicalHackPos )
{
- // Need to store the uncompressed size in the manifest
pValue[6].Name = sDigestProperty;
pValue[6].Value <<= pStream->getDigest();
pStream->SetIsEncrypted ( sal_True );
@@ -503,6 +518,8 @@ void ZipPackageFolder::saveContents(OUString &rPath, std::vector < Sequence < Pr
// Then copy it back afterwards...
ZipPackageFolder::copyZipEntry ( pStream->aEntry, *pTempEntry );
+ // all the dangerous stuff has passed, so we can release pTempEntry
+ pTempEntry.release();
pStream->aEntry.sName = rShortName;
pStream->aEntry.nOffset *= -1;
}