From 1746feadee3f190f7a0ce2363f9c51cf02991d90 Mon Sep 17 00:00:00 2001 From: Martin Gallwey Date: Wed, 5 Sep 2001 17:48:26 +0000 Subject: #91797# Finish XFileStream with an underlying XTempFile instead of an osl::File --- package/source/zipapi/XFileStream.cxx | 215 +++++++++++++++++++++++----------- package/source/zipapi/XFileStream.hxx | 47 ++++++-- 2 files changed, 183 insertions(+), 79 deletions(-) (limited to 'package') diff --git a/package/source/zipapi/XFileStream.cxx b/package/source/zipapi/XFileStream.cxx index 34d0941b6f51..f1340ec9706f 100644 --- a/package/source/zipapi/XFileStream.cxx +++ b/package/source/zipapi/XFileStream.cxx @@ -2,9 +2,9 @@ * * $RCSfile: XFileStream.cxx,v $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * - * last change: $Author: mtg $ $Date: 2001-07-04 14:56:24 $ + * last change: $Author: mtg $ $Date: 2001-09-05 18:47:36 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -61,23 +61,67 @@ #ifndef _XFILE_STREAM_HXX #include #endif -#ifndef _OSL_FILE_HXX_ -#include +#ifndef _ENCRYPTION_DATA_HXX_ +#include +#endif +#ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPCONSTANTS_HPP_ +#include +#endif +#ifndef _PACKAGE_CONSTANTS_HXX_ +#include +#endif +#ifndef _RTL_CIPHER_H_ +#include +#endif +#ifndef _ZIP_FILE_HXX +#include #endif #include // for memcpy -using namespace osl; +using namespace com::sun::star::packages::zip::ZipConstants; using namespace com::sun::star::io; using namespace com::sun::star::uno; +using com::sun::star::lang::IllegalArgumentException; +using ::rtl::OUString; -XFileStream::XFileStream( File * pNewFile ) -: pFile (pNewFile ) +XFileStream::XFileStream( com::sun::star::packages::zip::ZipEntry & rEntry, + com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewZipStream, + com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewTempStream, + const vos::ORef < EncryptionData > &rData, + sal_Bool bNewRawStream ) +: maEntry ( rEntry ) +, mxData ( rData ) +, mbRawStream ( bNewRawStream ) +, mbFinished ( sal_False ) +, mxTempIn ( xNewTempStream ) +, mxTempSeek ( xNewTempStream, UNO_QUERY ) +, mxTempOut ( xNewTempStream, UNO_QUERY ) +, mxZipStream ( xNewZipStream ) +, mxZipSeek ( xNewZipStream, UNO_QUERY ) +, maInflater ( sal_True ) +, maCipher ( NULL ) { + mnZipCurrent = maEntry.nOffset; + if (mbRawStream) + { + mnZipSize = maEntry.nMethod == DEFLATED ? maEntry.nCompressedSize : maEntry.nSize; + mnZipEnd = maEntry.nOffset + mnZipSize; + } + else + { + mnZipSize = maEntry.nSize; + mnZipEnd = maEntry.nMethod == DEFLATED ? maEntry.nOffset + maEntry.nCompressedSize : maEntry.nOffset + maEntry.nSize; + } + if ( rData->aSalt.getLength() ) + ZipFile::StaticGetCipher ( rData, maCipher ); } -XFileStream::~XFileStream(void) + +XFileStream::~XFileStream() { - delete pFile; + if ( maCipher ) + rtl_cipher_destroy ( maCipher ); } + Any SAL_CALL XFileStream::queryInterface( const Type& rType ) throw(RuntimeException) { @@ -90,105 +134,136 @@ Any SAL_CALL XFileStream::queryInterface( const Type& rType ) static_cast< XSeekable* > ( this ) ); } + void SAL_CALL XFileStream::acquire(void) throw() { OWeakObject::acquire(); } + void SAL_CALL XFileStream::release(void) throw() { OWeakObject::release(); } -sal_Int32 SAL_CALL XFileStream::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) - throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) + +void XFileStream::fill( sal_Int64 nUntil) { - if (nBytesToRead < 0) - throw BufferSizeExceededException(::rtl::OUString(),*this); + sal_Int32 nRead; + sal_Int64 nPosition = mxTempSeek->getPosition(); + mxTempSeek->seek ( mxTempSeek->getLength() ); + maBuffer.realloc ( n_ConstBufferSize ); + + while ( mxTempSeek->getLength() < nUntil ) + { + if ( !mbRawStream ) + { + while ( 0 == ( nRead = maInflater.doInflate( maBuffer ) ) ) + { + if ( maInflater.finished() || maInflater.needsDictionary() ) + { + // some error handling ? + return; + } + + sal_Int64 nDiff = mnZipEnd - mnZipCurrent; + if ( nDiff >= 0 ) + { + mxZipSeek->seek ( mnZipCurrent ); + nRead = mxZipStream->readBytes ( maCompBuffer, static_cast < sal_Int32 > ( nDiff < n_ConstBufferSize ? nDiff : n_ConstBufferSize ) ); + mnZipCurrent += nRead; + // maCompBuffer now has the uncompressed data, check if we need to decrypt + // before passing to the Inflater + if ( maCipher ) + { + Sequence < sal_Int8 > aCryptBuffer ( nRead ); + rtlCipherError aResult = rtl_cipher_decode ( maCipher, + maCompBuffer.getConstArray(), + nRead, + reinterpret_cast < sal_uInt8 * > (aCryptBuffer.getArray()), + nRead); + OSL_ASSERT (aResult == rtl_Cipher_E_None); + maCompBuffer = aCryptBuffer; // Now it holds the decrypted data - sal_uInt64 nBytesRead = 0; - aData.realloc ( nBytesToRead ); - FileBase::RC nError = pFile->read ( aData.getArray(), nBytesToRead, nBytesRead ); + } + maInflater.setInput ( maCompBuffer ); + } + else + { + // some error handling ? + return; + } + } + } + else + { + sal_Int64 nDiff = mnZipEnd - mnZipCurrent; + mxZipSeek->seek ( mnZipCurrent ); + nRead = mxZipStream->readBytes ( maBuffer, static_cast < sal_Int32 > ( nDiff < n_ConstBufferSize ? nDiff : n_ConstBufferSize ) ); + mnZipCurrent += nRead; + } + Sequence < sal_Int8 > aTmpBuffer ( maBuffer.getConstArray(), nRead ); + mxTempOut->writeBytes ( aTmpBuffer ); + } + mxTempSeek->seek ( nPosition ); +} - if ( nError != FileBase::E_None ) - throw IOException (); +sal_Int32 SAL_CALL XFileStream::readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) + throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) +{ + sal_Int64 nPosition = mxTempSeek->getPosition(); + if ( nPosition + nBytesToRead > mnZipSize ) + nBytesToRead = static_cast < sal_Int32 > ( mnZipSize - nPosition ); - return static_cast < sal_Int32 > (nBytesRead); + sal_Int64 nUntil = nBytesToRead + nPosition + n_ConstBufferSize; + if (nUntil > mnZipSize ) + nUntil = mnZipSize; + if ( nUntil > mxTempSeek->getLength() ) + fill ( nUntil ); + sal_Int32 nRead = mxTempIn->readBytes ( aData, nBytesToRead ); + return nRead; } sal_Int32 SAL_CALL XFileStream::readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) - throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) + throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) { - return readBytes(aData, nMaxBytesToRead); + return readBytes ( aData, nMaxBytesToRead ); } void SAL_CALL XFileStream::skipBytes( sal_Int32 nBytesToSkip ) - throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) + throw( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) { - if (nBytesToSkip < 0) - throw BufferSizeExceededException(::rtl::OUString(),*this); - - FileBase::RC nError = pFile->setPos ( osl_Pos_Current, nBytesToSkip ); - if ( nError != FileBase::E_None ) - throw IOException (); + seek ( mxTempSeek->getPosition() + nBytesToSkip ); } sal_Int32 SAL_CALL XFileStream::available( ) - throw(NotConnectedException, IOException, RuntimeException) + throw( NotConnectedException, IOException, RuntimeException) { - sal_uInt64 nPos, nEndPos; - sal_Int32 nResult = 0; - FileBase::RC nError = pFile->getPos ( nPos ); - if ( nError != FileBase::E_None ) - throw IOException (); - nError = pFile->setPos ( osl_Pos_End, 0 ); - if ( nError != FileBase::E_None ) - throw IOException (); - nError = pFile->getPos ( nEndPos ); - if ( nError != FileBase::E_None ) - throw IOException (); - nResult = static_cast < sal_Int32 > ( nEndPos - nPos ); - nError = pFile->setPos ( osl_Pos_Absolut, nPos ); - if ( nError != FileBase::E_None ) - throw IOException (); - return nResult; + return static_cast < sal_Int32 > ( mnZipSize - mxTempSeek->getPosition() ); } void SAL_CALL XFileStream::closeInput( ) - throw(NotConnectedException, IOException, RuntimeException) + throw( NotConnectedException, IOException, RuntimeException) { - pFile->close(); } void SAL_CALL XFileStream::seek( sal_Int64 location ) - throw(::com::sun::star::lang::IllegalArgumentException, IOException, RuntimeException) + throw( IllegalArgumentException, IOException, RuntimeException) { - FileBase::RC nError = pFile->setPos ( osl_Pos_Absolut, location ); - if ( nError != FileBase::E_None ) - throw IOException (); + if ( location > mnZipSize || location < 0 ) + throw IllegalArgumentException(); + if ( location > mxTempSeek->getLength() ) + { + sal_Int64 nUntil = location + n_ConstBufferSize > mnZipSize ? mnZipSize : location + n_ConstBufferSize; + fill ( nUntil ); + } + mxTempSeek->seek ( location ); } sal_Int64 SAL_CALL XFileStream::getPosition( ) throw(IOException, RuntimeException) { - sal_uInt64 nPos; - FileBase::RC nError = pFile->getPos ( nPos ); - if ( nError != FileBase::E_None ) - throw IOException (); - return nPos; + return mxTempSeek->getPosition(); } sal_Int64 SAL_CALL XFileStream::getLength( ) throw(IOException, RuntimeException) { - sal_uInt64 nPos, nEndPos; - FileBase::RC nError = pFile->getPos ( nPos ); - if ( nError != FileBase::E_None ) - throw IOException (); - nError = pFile->setPos ( osl_Pos_End, 0 ); - if ( nError != FileBase::E_None ) - throw IOException (); - nError = pFile->getPos ( nEndPos ); - if ( nError != FileBase::E_None ) - throw IOException (); - nError = pFile->setPos ( osl_Pos_Absolut, nPos ); - if ( nError != FileBase::E_None ) - throw IOException (); - return nEndPos; + return mnZipSize; } diff --git a/package/source/zipapi/XFileStream.hxx b/package/source/zipapi/XFileStream.hxx index c6751a1477e4..4236177d1e41 100644 --- a/package/source/zipapi/XFileStream.hxx +++ b/package/source/zipapi/XFileStream.hxx @@ -2,9 +2,9 @@ * * $RCSfile: XFileStream.hxx,v $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * - * last change: $Author: mtg $ $Date: 2001-07-04 14:56:24 $ + * last change: $Author: mtg $ $Date: 2001-09-05 18:48:26 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -73,28 +73,57 @@ #ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_ #include #endif +#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_ +#include +#endif #ifndef _CPPUHELPER_WEAK_HXX_ #include #endif +#ifndef COM_SUN_STAR_PACKAGES_ZIP_ZIPENTRY_HPP +#include +#endif +#ifndef _VOS_REF_H_ +#include +#endif +#ifndef _INFLATER_HXX +#include +#endif -namespace osl { class File; } - +class EncryptionData; +typedef void* rtlCipher; class XFileStream : public com::sun::star::io::XInputStream, public com::sun::star::io::XSeekable, public cppu::OWeakObject { protected: - osl::File *pFile; + com::sun::star::uno::Reference < com::sun::star::io::XInputStream > mxZipStream; + com::sun::star::uno::Reference < com::sun::star::io::XSeekable > mxZipSeek; + com::sun::star::uno::Reference < com::sun::star::io::XInputStream > mxTempIn; + com::sun::star::uno::Reference < com::sun::star::io::XSeekable > mxTempSeek; + com::sun::star::uno::Reference < com::sun::star::io::XOutputStream > mxTempOut; + com::sun::star::uno::Sequence < sal_Int8 > maBuffer, maCompBuffer; + com::sun::star::packages::zip::ZipEntry maEntry; + vos::ORef < EncryptionData > mxData; + rtlCipher maCipher; + Inflater maInflater; + sal_Bool mbRawStream, mbFinished; + sal_Int64 mnZipCurrent, mnZipEnd, mnZipSize; + void fill( sal_Int64 nUntil ); + public: - XFileStream( osl::File * pNewFile ); - virtual ~XFileStream(void); + XFileStream( com::sun::star::packages::zip::ZipEntry & rEntry, + com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewZipStream, + com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewTempStream, + const vos::ORef < EncryptionData > &rData, + sal_Bool bRawStream ); + virtual ~XFileStream(); // XInterface virtual com::sun::star::uno::Any SAL_CALL queryInterface( const com::sun::star::uno::Type& rType ) throw(com::sun::star::uno::RuntimeException); - virtual void SAL_CALL acquire(void) + virtual void SAL_CALL acquire() throw(); - virtual void SAL_CALL release(void) + virtual void SAL_CALL release() throw(); // XInputStream virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) -- cgit