diff options
author | Mikhail Voitenko <mav@openoffice.org> | 2002-02-27 14:51:57 +0000 |
---|---|---|
committer | Mikhail Voitenko <mav@openoffice.org> | 2002-02-27 14:51:57 +0000 |
commit | 7f4bd5e20c945ecae2cd2bc43af9cd5616e1a262 (patch) | |
tree | 994c54194740faecd4c4dbe716a6e93edf325979 /package | |
parent | 0b02ac946291683a1090c2c2acddc858dc11f451 (diff) |
#97587# truncate the original file before streaming in to it
Diffstat (limited to 'package')
-rw-r--r-- | package/inc/ZipPackage.hxx | 9 | ||||
-rw-r--r-- | package/source/zippackage/ZipPackage.cxx | 148 |
2 files changed, 118 insertions, 39 deletions
diff --git a/package/inc/ZipPackage.hxx b/package/inc/ZipPackage.hxx index 0482b133e1cf..db00afe13078 100644 --- a/package/inc/ZipPackage.hxx +++ b/package/inc/ZipPackage.hxx @@ -2,9 +2,9 @@ * * $RCSfile: ZipPackage.hxx,v $ * - * $Revision: 1.30 $ + * $Revision: 1.31 $ * - * last change: $Author: mav $ $Date: 2002-02-19 17:00:52 $ + * last change: $Author: mav $ $Date: 2002-02-27 15:51:57 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -99,7 +99,7 @@ class ZipFile; class ByteGrabber; namespace com { namespace sun { namespace star { namespace container { class XNameContainer; } - namespace io { class XStream; class XOutputStream; class XInputStream; class XSeekable; } + namespace io { class XStream; class XOutputStream; class XInputStream; class XSeekable; class XActiveDataStreamer; } namespace lang { class XMultiServiceFactory; } namespace task { class XInteractionHandler; } } } } @@ -147,7 +147,8 @@ protected: ZipFile *pZipFile; void getZipFileContents(); - sal_Bool writeFileIsTemp( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& ); + sal_Bool writeFileIsTemp(); + ::com::sun::star::uno::Reference < ::com::sun::star::io::XActiveDataStreamer > openOriginalForOutput(); public: ZipPackage (const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > &xNewFactory); diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index 580cd8c2935f..26294ba7c48c 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -2,9 +2,9 @@ * * $RCSfile: ZipPackage.cxx,v $ * - * $Revision: 1.77 $ + * $Revision: 1.78 $ * - * last change: $Author: mav $ $Date: 2002-02-22 16:00:56 $ + * last change: $Author: mav $ $Date: 2002-02-27 15:47:38 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -166,6 +166,8 @@ #include <memory> #include <vector> +#include <unotools/localfilehelper.hxx> +#include <tools/debug.hxx> using namespace rtl; using namespace ucb; @@ -203,6 +205,29 @@ public: { mStream = stream; } }; +class DummyInputStream : public ::cppu::WeakImplHelper1< XInputStream > +{ + virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) + throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) + { return 0; } + + virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) + throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) + { return 0; } + + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) + throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) + {} + + virtual sal_Int32 SAL_CALL available() + throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) + { return 0; } + + virtual void SAL_CALL closeInput() + throw ( NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) + {} +}; + //=========================================================================== static void copyInputToOutput( Reference< XInputStream >& aIn, Reference< XOutputStream >& aOut ) @@ -686,20 +711,28 @@ Reference< XInterface > SAL_CALL ZipPackage::createInstanceWithArguments( const return xRef; } -sal_Bool ZipPackage::writeFileIsTemp( Reference< XOutputStream >& aOrigStream ) +sal_Bool ZipPackage::writeFileIsTemp() { // In case the target local file does not exist or empty // write directly to it otherwize create a temporary file to write to sal_Bool aUseTemp = sal_True; Reference < XOutputStream > xTempOut; + Reference< XActiveDataStreamer > xSink; - if ( eMode == e_IMode_URL && !pZipFile && aOrigStream.is() ) + if ( eMode == e_IMode_URL && !pZipFile + && ::utl::LocalFileHelper::IsLocalFile( sURL ) ) { - xTempOut = aOrigStream; - aUseTemp = sal_False; + xSink = openOriginalForOutput(); + if( xSink.is() ) + { + xTempOut = xSink->getStream()->getOutputStream(); + if( xTempOut.is() ) + aUseTemp = sal_False; + } } - else + + if( aUseTemp ) { // create temporary file const OUString sServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) ); @@ -823,8 +856,29 @@ sal_Bool ZipPackage::writeFileIsTemp( Reference< XOutputStream >& aOrigStream ) } // Update our References to point to the new temp file - xContentStream = Reference < XInputStream > ( xTempOut, UNO_QUERY ); - xContentSeek = Reference < XSeekable > ( xTempOut, UNO_QUERY ); + if( aUseTemp ) + { + xContentStream = Reference < XInputStream > ( xTempOut, UNO_QUERY ); + xContentSeek = Reference < XSeekable > ( xTempOut, UNO_QUERY ); + } + else + { + // the case when the original file was written directly + + try + { + // the output should be closed after request fo input + // to avoid file closing + xContentStream = xSink->getStream()->getInputStream(); + xTempOut->closeOutput(); + xContentSeek = Reference < XSeekable > ( xContentStream, UNO_QUERY ); + } + catch( Exception& ) + { + } + + DBG_ASSERT( xContentStream.is() && xContentSeek.is(), "XSeekable interface is required!" ); + } // seek back to the beginning of the temp file so we can read segments from it xContentSeek->seek ( 0 ); @@ -836,31 +890,29 @@ sal_Bool ZipPackage::writeFileIsTemp( Reference< XOutputStream >& aOrigStream ) return aUseTemp; } -// XChangesBatch -void SAL_CALL ZipPackage::commitChanges( ) - throw(WrappedTargetException, RuntimeException) +Reference< XActiveDataStreamer > ZipPackage::openOriginalForOutput() { - if ( eMode == e_IMode_XInputStream ) - { - IOException aException; - throw WrappedTargetException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "This package is read only!" ) ), - static_cast < OWeakObject * > ( this ), makeAny ( aException ) ); - } - + // open and truncate the original file Content aOriginalContent (sURL, Reference < XCommandEnvironment >() ); - Reference< XOutputStream > aOrigFileStream; + Reference< XActiveDataStreamer > xSink = new ActiveDataStreamer; if ( eMode == e_IMode_URL ) { - // local file can be written directly if it empty or does not exist - - Reference< XActiveDataStreamer > xSink = new ActiveDataStreamer; - try { - // to be sure that the file exists - if( !pZipFile ) - aOriginalContent.writeStream( Reference< XInputStream >(), sal_False ); + try + { + sal_Int64 aSize = 0; + aOriginalContent.setPropertyValue( OUString::createFromAscii( "Size" ), makeAny( aSize ) ); + } + catch( Exception& ) + { + // the file is not accessible + // just try to write an empty stream to it + + Reference< XInputStream > xTempIn = new DummyInputStream; //Reference< XInputStream >( xTempOut, UNO_QUERY ); + aOriginalContent.writeStream( xTempIn , sal_True ); + } OpenCommandArgument2 aArg; aArg.Mode = OpenMode::DOCUMENT; @@ -869,8 +921,6 @@ void SAL_CALL ZipPackage::commitChanges( ) aArg.Properties = Sequence< Property >( 0 ); // unused aOriginalContent.executeCommand( OUString::createFromAscii( "open" ), makeAny( aArg ) ); - - aOrigFileStream = xSink->getStream()->getOutputStream(); } catch( Exception& ) { @@ -879,21 +929,47 @@ void SAL_CALL ZipPackage::commitChanges( ) } } + return xSink; +} + +// XChangesBatch +void SAL_CALL ZipPackage::commitChanges( ) + throw(WrappedTargetException, RuntimeException) +{ + if ( eMode == e_IMode_XInputStream ) + { + IOException aException; + throw WrappedTargetException( OUString( RTL_CONSTASCII_USTRINGPARAM ( "This package is read only!" ) ), + static_cast < OWeakObject * > ( this ), makeAny ( aException ) ); + } + RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "{ ZipPackage::commitChanges" ); // First we write the entire package to a temporary file. After writeTempFile, // xContentSeek and xContentStream will reference the new temporary file. // Exception - empty or nonexistent local file that is written directly - if ( writeFileIsTemp( aOrigFileStream ) && eMode == e_IMode_URL ) + if ( writeFileIsTemp() && eMode == e_IMode_URL ) { - if( aOrigFileStream.is() ) + Reference< XOutputStream > aOrigFileStream; + + if( ::utl::LocalFileHelper::IsLocalFile( sURL ) ) { // write directly in case of local file - copyInputToOutput( xContentStream, aOrigFileStream ); - aOrigFileStream->closeOutput(); - xContentSeek->seek ( 0 ); + Reference< XActiveDataStreamer > xSink = openOriginalForOutput(); + + if( xSink.is() ) + { + aOrigFileStream = xSink->getStream()->getOutputStream(); + if( aOrigFileStream.is() ) + { + copyInputToOutput( xContentStream, aOrigFileStream ); + aOrigFileStream->closeOutput(); + xContentSeek->seek ( 0 ); + } + } } - else + + if( !aOrigFileStream.is() ) { Reference < XPropertySet > xPropSet ( xContentStream, UNO_QUERY ); if ( xPropSet.is() ) @@ -928,6 +1004,8 @@ void SAL_CALL ZipPackage::commitChanges( ) // not quite sure how it could happen that xContentStream WOULDN'T support // XPropertySet, but just in case... :) + Content aOriginalContent (sURL, Reference < XCommandEnvironment >() ); + try { aOriginalContent.writeStream ( xContentStream, sal_True ); |