diff options
author | Martin Gallwey <mtg@openoffice.org> | 2001-11-15 19:42:43 +0000 |
---|---|---|
committer | Martin Gallwey <mtg@openoffice.org> | 2001-11-15 19:42:43 +0000 |
commit | 9f5f9dac37e81cb3665ba2d88df6a2a643f60fe9 (patch) | |
tree | d259541ded8226d15f37ec0fdd135b384274e750 /package | |
parent | d13c7fc98effcef0c9b6cf8e7858e9aa472b78bf (diff) |
#94679#, #92268# support XServiceInfo and encrypted data headers
Diffstat (limited to 'package')
-rw-r--r-- | package/source/zippackage/ZipPackage.cxx | 944 |
1 files changed, 489 insertions, 455 deletions
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index c2077aad445b..b1a7e06b4512 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -2,9 +2,9 @@ * * $RCSfile: ZipPackage.cxx,v $ * - * $Revision: 1.69 $ + * $Revision: 1.70 $ * - * last change: $Author: mtg $ $Date: 2001-10-30 10:34:23 $ + * last change: $Author: mtg $ $Date: 2001-11-15 20:42:43 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -97,23 +97,29 @@ #ifndef _COM_SUN_STAR_PACKAGES_MANIFEST_XMANIFESTWRITER_HPP_ #include <com/sun/star/packages/manifest/XManifestWriter.hpp> #endif -#ifndef _COM_SUN_STAR_UCB_INTERACTIVEAUGMENTEDIOEXCEPTION_HPP_ -#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> +#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_ +#include <com/sun/star/io/XStream.hpp> #endif -#ifndef _COM_SUN_STAR_UCB_INTERACTIVEWRONGMEDIUMEXCEPTION_HPP_ -#include <com/sun/star/ucb/InteractiveWrongMediumException.hpp> +#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_ +#include <com/sun/star/io/XInputStream.hpp> #endif -#ifndef _COM_SUN_STAR_UCB_IOERRORCODE_HPP -#include <com/sun/star/ucb/IOErrorCode.hpp> +#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_ +#include <com/sun/star/io/XOutputStream.hpp> #endif #ifndef _COM_SUN_STAR_IO_XTRUNCATE_HPP_ #include <com/sun/star/io/XTruncate.hpp> #endif -#ifndef _RTL_USTRBUF_HXX_ -#include <rtl/ustrbuf.hxx> +#ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_ +#include <com/sun/star/io/XSeekable.hpp> #endif -#ifndef _INTERACTION_REQUEST_HXX_ -#include <InteractionRequest.hxx> +#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#endif +#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_ +#include <com/sun/star/container/XNameContainer.hpp> +#endif +#ifndef _COM_SUN_STAR_UCB_IOERRORCODE_HPP_ +#include <com/sun/star/ucb/IOErrorCode.hpp> #endif #ifndef _UCBHELPER_CONTENT_HXX #include <ucbhelper/content.hxx> @@ -130,16 +136,44 @@ #ifndef _CONTENT_INFO_HXX_ #include <ContentInfo.hxx> #endif -#ifndef _RTL_LOGFILE_HXX_ -#include <rtl/logfile.hxx> -#endif #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ #include <cppuhelper/typeprovider.hxx> #endif #ifndef _RTL_URI_HXX_ #include <rtl/uri.hxx> #endif +#ifndef _RTL_RANDOM_H_ +#include <rtl/random.h> +#endif +#ifndef _RTL_LOGFILE_HXX_ +#include <rtl/logfile.hxx> +#endif +#ifndef _OSL_TIME_H_ +#include <osl/time.h> +#endif #include <memory> +#include <vector> + +// pack'n'go headers +#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_ +#include <com/sun/star/task/XInteractionHandler.hpp> +#endif +#ifndef _INTERACTION_REQUEST_HXX_ +#include <InteractionRequest.hxx> +#endif +#ifndef _RTL_USTRBUF_HXX_ +#include <rtl/ustrbuf.hxx> +#endif +#ifndef _COM_SUN_STAR_UCB_INTERACTIVEAUGMENTEDIOEXCEPTION_HPP_ +#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp> +#endif +#ifndef _OSL_FILE_HXX_ +#include <osl/file.hxx> +#endif +#ifndef _COM_SUN_STAR_UCB_INTERACTIVEWRONGMEDIUMEXCEPTION_HPP_ +#include <com/sun/star/ucb/InteractiveWrongMediumException.hpp> +#endif + using namespace rtl; using namespace ucb; @@ -159,6 +193,7 @@ using namespace com::sun::star::packages::zip; using namespace com::sun::star::packages::manifest; using namespace com::sun::star::packages::zip::ZipConstants; + #define LOGFILE_AUTHOR "mg115289" struct SuffixGenerator @@ -220,14 +255,12 @@ char * ImplGetChars( const OUString & rString ) return pChar; } #endif - ZipPackage::ZipPackage (const Reference < XMultiServiceFactory > &xNewFactory) : pZipFile( NULL ) , pRootFolder( NULL ) , xFactory( xNewFactory ) , bHasEncryptedEntries ( sal_False ) , eMode ( e_IMode_None ) -, nSegmentSize ( 0 ) { xRootFolder = pRootFolder = new ZipPackageFolder(); } @@ -357,14 +390,14 @@ void ZipPackage::getZipFileContents() Reference < XUnoTunnel > xTunnel; aAny >>= xTunnel; sal_Int64 nTest=0; - if ((nTest = xTunnel->getSomething(ZipPackageFolder::getUnoTunnelImplementationId())) != 0) + if ((nTest = xTunnel->getSomething(ZipPackageFolder::static_getImplementationId())) != 0) { pFolder = reinterpret_cast < ZipPackageFolder* > ( nTest ); pFolder->SetMediaType ( sMediaType ); } else { - pStream = reinterpret_cast < ZipPackageStream* > ( xTunnel->getSomething(ZipPackageStream::getUnoTunnelImplementationId())); + pStream = reinterpret_cast < ZipPackageStream* > ( xTunnel->getSomething(ZipPackageStream::static_getImplementationId())); pStream->SetMediaType ( sMediaType ); if (pSalt && pVector && pCount && pSize) @@ -392,7 +425,9 @@ void ZipPackage::getZipFileContents() } pStream->SetToBeEncrypted ( sal_True ); - bHasEncryptedEntries = sal_True; + pStream->SetIsEncrypted ( sal_True ); + if ( !bHasEncryptedEntries && pStream->getName().compareToAscii ( "content.xml" ) == 0 ) + bHasEncryptedEntries = sal_True; } } } @@ -411,106 +446,99 @@ void SAL_CALL ZipPackage::initialize( const Sequence< Any >& aArguments ) RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "{ ZipPackage::initialize" ); sal_Bool bBadZipFile = sal_False, bHaveZipFile = sal_True, bSpanned = sal_False; - if ( (aArguments[0] >>= sURL)) + if ( aArguments.getLength() ) { - eMode = e_IMode_URL; -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: initialise called on %s\n", ImplGetChars ( sURL ) ); -#endif - try + if ( (aArguments[0] >>= sURL)) { - Content aContent (sURL, Reference < XCommandEnvironment >() ); - Reference < XActiveDataSink > xSink = new ZipPackageSink; - if (aContent.openStream ( xSink ) ) - xContentStream = xSink->getInputStream(); + eMode = e_IMode_URL; + try + { + Content aContent (sURL, Reference < XCommandEnvironment >() ); + Reference < XActiveDataSink > xSink = new ZipPackageSink; + if (aContent.openStream ( xSink ) ) + xContentStream = xSink->getInputStream(); + } + catch (com::sun::star::uno::Exception&) + { + // Exception derived from uno::Exception thrown. This probably + // means the file doesn't exist...we'll create it at + // commitChanges time + bHaveZipFile = sal_False; + } } - catch (com::sun::star::uno::Exception&) + else if ( (aArguments[0] >>= xContentStream) ) { - // Exception derived from uno::Exception thrown. This probably - // means the file doesn't exist...we'll create it at - // commitChanges time - bHaveZipFile = sal_False; + eMode = e_IMode_XInputStream; } - } - else if ( (aArguments[0] >>= xContentStream) ) - { - eMode = e_IMode_XInputStream; -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: initialise called with an XInputStream\n" ); -#endif - } - else if ( (aArguments[0] >>= xStream ) ) - { - eMode = e_IMode_XStream; - xContentStream = xStream->getInputStream(); -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: initialise called with an XInputStream\n" ); -#endif - } - else - // The URL is not acceptable - throw com::sun::star::uno::Exception ( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Bad URL." ) ), - static_cast < ::cppu::OWeakObject * > ( this ) ); - - try - { - if (xContentStream.is()) + else if ( (aArguments[0] >>= xStream ) ) { - xContentSeek = Reference < XSeekable > ( xContentStream, UNO_QUERY ); - if ( ! xContentSeek.is() ) - throw com::sun::star::uno::Exception ( OUString( RTL_CONSTASCII_USTRINGPARAM ( "The package component _requires_ an XSeekable interface!" ) ), - static_cast < ::cppu::OWeakObject * > ( this ) ); + eMode = e_IMode_XStream; + xContentStream = xStream->getInputStream(); + } + else + // The URL is not acceptable + throw com::sun::star::uno::Exception ( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Bad URL." ) ), + static_cast < ::cppu::OWeakObject * > ( this ) ); - if ( eMode == e_IMode_URL) // spanned files only supported if initialised with a URL + try + { + if (xContentStream.is()) { - Sequence < sal_Int8 > aSequence ( 4 ); - if ( 4 == xContentStream->readBytes( aSequence, 4 ) ) + xContentSeek = Reference < XSeekable > ( xContentStream, UNO_QUERY ); + if ( ! xContentSeek.is() ) + throw com::sun::star::uno::Exception ( OUString( RTL_CONSTASCII_USTRINGPARAM ( "The package component _requires_ an XSeekable interface!" ) ), + static_cast < ::cppu::OWeakObject * > ( this ) ); + if ( eMode == e_IMode_URL) // spanned files only supported if initialised with a URL { - xContentSeek->seek ( 0 ); - const sal_Int8 *pSeq = aSequence.getConstArray(); - if (pSeq[0] == 'P' && - pSeq[1] == 'K' && - pSeq[2] == 7 && - pSeq[3] == 8 ) - bSpanned = sal_True; + Sequence < sal_Int8 > aSequence ( 4 ); + if ( 4 == xContentStream->readBytes( aSequence, 4 ) ) + { + xContentSeek->seek ( 0 ); + const sal_Int8 *pSeq = aSequence.getConstArray(); + if (pSeq[0] == 'P' && + pSeq[1] == 'K' && + pSeq[2] == 7 && + pSeq[3] == 8 ) + bSpanned = sal_True; + } } } + else + bHaveZipFile = sal_False; } - else - bHaveZipFile = sal_False; - } - catch (com::sun::star::uno::Exception&) - { - // Exception derived from uno::Exception thrown. This probably - // means the file doesn't exist...we'll create it at - // commitChanges time - bHaveZipFile = sal_False; - } - if ( bHaveZipFile ) - { - try - { - if ( bSpanned ) - // after unSpanFile, xContentStream will refer to the tempfile containing - // the unspanned file - unSpanFile (); - pZipFile = new ZipFile ( xContentStream, xFactory, sal_True ); - getZipFileContents(); - } - catch ( IOException & ) - { - bBadZipFile = sal_True; - } - catch ( ZipException & ) + catch (com::sun::star::uno::Exception&) { - bBadZipFile = sal_True; + // Exception derived from uno::Exception thrown. This probably + // means the file doesn't exist...we'll create it at + // commitChanges time + bHaveZipFile = sal_False; } - if ( bBadZipFile ) + if ( bHaveZipFile ) { - // clean up the memory, and tell the UCB about the error - delete pZipFile; pZipFile = NULL; - throw com::sun::star::uno::Exception ( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Bad Zip File." ) ), - static_cast < ::cppu::OWeakObject * > ( this ) ); + try + { + if ( bSpanned ) + // after unSpanFile, xContentStream will refer to the tempfile containing + // the unspanned file + unSpanFile (); + pZipFile = new ZipFile ( xContentStream, xFactory, sal_True ); + getZipFileContents(); + } + catch ( IOException & ) + { + bBadZipFile = sal_True; + } + catch ( ZipException & ) + { + bBadZipFile = sal_True; + } + if ( bBadZipFile ) + { + // clean up the memory, and tell the UCB about the error + delete pZipFile; pZipFile = NULL; + throw com::sun::star::uno::Exception ( OUString( RTL_CONSTASCII_USTRINGPARAM ( "Bad Zip File." ) ), + static_cast < ::cppu::OWeakObject * > ( this ) ); + } } } RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "} ZipPackage::initialize" ); @@ -701,10 +729,6 @@ void ZipPackage::writeTempFile() const OUString sServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) ); Reference < XOutputStream > xTempOut = Reference < XOutputStream > ( xFactory->createInstance ( sServiceName ), UNO_QUERY ); -#ifdef MTG_DEBUG - fprintf(stderr, "We have a %s tempfile!\n", xTempOut.is() ? "good" : "bad" ); -#endif - // Hand it to the ZipOutputStream: ZipOutputStream aZipOut ( xTempOut, nSegmentSize != 0); aZipOut.setMethod(DEFLATED); @@ -998,339 +1022,9 @@ void SAL_CALL ZipPackage::commitChanges( ) while ( eRet != e_Finished ); } } -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: ZipPackage Commit finished\n"); -#endif RTL_LOGFILE_TRACE_AUTHOR ( "package", LOGFILE_AUTHOR, "} ZipPackage::commitChanges" ); } -sal_Int32 ZipPackage::RequestDisk ( OUString &rMountPath, sal_Int16 nDiskNum) -{ - VolumeInfo aInfo ( osl_VolumeInfo_Mask_FreeSpace | osl_VolumeInfo_Mask_DeviceHandle | osl_VolumeInfo_Mask_Attributes ); - VolumeDevice aDevice; - FileBase::RC aRC; - - do - { - aRC = Directory::getVolumeInfo ( rMountPath, aInfo ); -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: Requesting disk for %s, result is %d\n", ImplGetChars ( rMountPath ), aRC ); -#endif - if ( aRC == FileBase::E_None ) - aDevice = aInfo.getDeviceHandle(); - else - { -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: Requesting disk calling HandleError with osl_File_E_INVAL\n" ); -#endif - if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, rMountPath) ) - return -1; - } - } - while ( aRC != FileBase::E_None ); -#ifdef UNX - do - { - aRC = aDevice.unmount(); -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: unmount returned %d\n", aRC ); -#endif - if ( aRC != FileBase::E_None ) - { - if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, rMountPath) ) - return -1; - } - } - while ( aRC != FileBase::E_None ); -#endif - - Any aExceptionAny, aMediumException; - InteractiveWrongMediumException aException; - aMediumException <<= static_cast < sal_Int16 > (nDiskNum-1); - aException.Medium = aMediumException; - aExceptionAny <<= aException; - if ( !HandleError ( aExceptionAny, EC_YES|EC_ABORT ) ) - return -1; -#ifdef UNX - do - { - aRC = aDevice.automount(); - -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: automount returned %d\n", aRC ); -#endif - if ( aRC != FileBase::E_None ) - { - if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, rMountPath) ) - return -1; - } - } - while ( aRC != FileBase::E_None ); - OUString aNewMountPath ( aDevice.getMountPath() ); - - if (aNewMountPath != rMountPath) - rMountPath = aNewMountPath; -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: returning, new mountpath is %s\n", ImplGetChars ( rMountPath ) ); -#endif -#endif - return FileBase::E_None; -} -SegmentEnum ZipPackage::writeSegment ( const OUString &rFileName, OUString &rMountPath, Reference < XInputStream > &xInBuffer, const sal_Int16 nDiskNum ) -{ - File *pFile = NULL; - FileBase::RC aRC; - sal_Bool bDynamicSpan = nSegmentSize < 0; - Sequence < sal_Int8 > aBuffer; - - sal_Int32 nRead = n_ConstBufferSize; - sal_uInt64 nLeft, nWritten; - VolumeInfo aInfo ( osl_VolumeInfo_Mask_FreeSpace | osl_VolumeInfo_Mask_DeviceHandle | osl_VolumeInfo_Mask_Attributes ); - -#ifdef MTG_DEBUG - fprintf (stderr, "MTG: In writeSegment, disk num is %d, file is %s, dir is %s\n", - nDiskNum, ImplGetChars(rFileName), ImplGetChars(rMountPath)); -#endif - do - { - aRC = Directory::getVolumeInfo ( rMountPath, aInfo ); -#ifdef MTG_DEBUG - fprintf(stderr, "MTG: getVolumeInfo returned %d\n", aRC ); -#endif - // return value is not useful, so we check if we have valid attributes instead - if ( aInfo.isValid ( osl_VolumeInfo_Mask_FreeSpace) ) - { - sal_Bool bReCheck; - OUStringBuffer aBuffer; - aBuffer.append ( rMountPath ); - if ( rMountPath.lastIndexOf ( '/' ) != rMountPath.getLength()-1 ) - aBuffer.appendAscii ( "/" ); - aBuffer.append ( rFileName ); - OUString sFullPath ( aBuffer.makeStringAndClear() ); - do - { - bReCheck = sal_False; - sal_uInt64 nFree = aInfo.getFreeSpace(); -#ifdef MTG_DEBUG - fprintf(stderr, "MTG: free is %d\n", static_cast < sal_Int32 > ( nFree ) ); -#endif - if ( ( bDynamicSpan && nFree < 1000 ) || - ( !bDynamicSpan && nFree < nSegmentSize ) ) - { - if ( !HandleError ( osl_File_E_NOSPC, EC_RETRY|EC_ABORT, sFullPath ) ) - { - if ( pFile ) - delete pFile; - return e_Aborted; - } - else - { - aRC = Directory::getVolumeInfo ( rMountPath, aInfo ); - bReCheck = sal_True; - } - } - else - { - nLeft = bDynamicSpan ? nFree : nSegmentSize; -#ifdef MTG_DEBUG - fprintf(stderr, "MTG: left is %ld\n", static_cast < sal_Int32 > ( nLeft ) ); -#endif - } - } - while ( bReCheck ); -#ifdef MTG_DEBUG - fprintf( stderr, "MTG: sDirectoryName is %s sFileName is %s FullPath is %s\n", - ImplGetChars ( rMountPath ), ImplGetChars ( rFileName ), ImplGetChars ( sFullPath ) ); -#endif - pFile = new File ( sFullPath ); - sal_Bool bExists = sal_False; - aRC = pFile->open ( osl_File_OpenFlag_Create | osl_File_OpenFlag_Write ); - if ( aRC == FileBase::E_EXIST ) - { - aRC = pFile->open ( osl_File_OpenFlag_Write ); - bExists = sal_True; - } - if ( aRC != FileBase::E_None ) - { -#ifdef MTG_DEBUG - fprintf(stderr, "MTG: file open returned %d\n", aRC ); -#endif - if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, sFullPath ) ) - { - delete pFile; - return e_Aborted; - } - } - else if ( bExists ) - { - // Truncate to 0 if necessary - aRC = pFile->setSize ( 0 ); - } - } - else - { - aRC = FileBase::E_IO; - if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, rMountPath ) ) - return e_Aborted; - } - } - while (aRC != FileBase::E_None ); - - // Now! We should have an open file on a disk which has at least nSegmentSize if not - // dynamic spanning and 1000 bytes if dynamic spanning. - - - // Let's read it all into the buffer in case something goes wrong and also - // so that the spannable checks in ByteChucker and ZipOutputStream work - - nRead = xInBuffer->readBytes ( aBuffer, static_cast < sal_Int32 > ( nLeft ) ); - - aRC = pFile->write ( aBuffer.getConstArray(), nRead, nWritten ); -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: write returned %d\n", aRC ); -#endif - - sal_Bool bRetry = sal_False; - - if ( nWritten != nRead || aRC != FileBase::E_None ) - bRetry = sal_True; - else - { - aRC = pFile->close (); -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: close returned %d\n", aRC ); -#endif - if ( aRC != FileBase::E_None ) - bRetry = sal_True; - } - delete pFile; - return nRead < nLeft ? e_Finished : bRetry ? e_Retry : e_Success; -} - -SegmentEnum ZipPackage::writeSegment ( const OUString &rFileName, Reference < XInputStream > &xInBuffer ) -{ - FileBase::RC aRC; - Sequence < sal_Int8 > aBuffer ( nSegmentSize ); - - sal_uInt64 nWritten; - - sal_Int32 nRead = xInBuffer->readBytes ( aBuffer, static_cast < sal_Int32 > ( nSegmentSize ) ); - - File aFile ( rFileName ); - aRC = aFile.open ( osl_File_OpenFlag_Create | osl_File_OpenFlag_Write ); - sal_Bool bExists = sal_False; - if ( aRC == FileBase::E_EXIST ) - { - aRC = aFile.open ( osl_File_OpenFlag_Write ); - bExists = sal_True; - } - if ( aRC != FileBase::E_None ) - { - if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, rFileName ) ) - return e_Aborted; - } - else if ( bExists ) - { - // truncate if necessary - aFile.setSize ( 0 ); - } - - aRC = aFile.write ( aBuffer.getConstArray(), nRead, nWritten ); -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: write returned %d\n", aRC ); -#endif - - sal_Bool bRetry = sal_False; - if ( nWritten != nRead || aRC != FileBase::E_None ) - bRetry = sal_True; - else - { - aRC = aFile.close (); -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: close returned %d\n", aRC ); -#endif - if ( aRC != FileBase::E_None ) - bRetry = sal_True; - } - return nRead < nSegmentSize ? e_Finished : bRetry ? e_Retry : e_Success; -} - -SegmentEnum ZipPackage::readSegment ( const OUString &rFileName, OUString &rMountPath, Reference < XOutputStream > &xTempOut, const sal_Int16 nDiskNum ) -{ - File *pFile = NULL; - FileBase::RC aRC; - SegmentEnum eRet; - - OUStringBuffer aStringBuffer; - aStringBuffer.append ( rMountPath ); - if ( rMountPath.lastIndexOf ( '/' ) != rMountPath.getLength()-1 ) - aStringBuffer.appendAscii ( "/" ); - aStringBuffer.append ( rFileName ); - OUString sFullPath ( aStringBuffer.makeStringAndClear() ); - -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: trying to read %s\n", ImplGetChars ( sFullPath ) ); -#endif - DirectoryItem aItem; - do - { - aRC = DirectoryItem::get ( sFullPath, aItem ); -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG: DirectoryItem::get returned %d\n", aRC ); -#endif - if ( aRC != FileBase::E_None && !HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, sFullPath ) ) - return e_Aborted; - } - while (aRC != FileBase::E_None ); - do - { - pFile = new File ( sFullPath ); - aRC = pFile->open ( osl_File_OpenFlag_Read ); -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG:file open returned %d\n", aRC ); -#endif - if ( aRC != FileBase::E_None ) - { - delete pFile; - if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, sFullPath ) ) - return e_Aborted; - } - } - while (aRC != FileBase::E_None ); - - FileStatus aStatus ( FileStatusMask_FileSize ); - aItem.getFileStatus ( aStatus ); - sal_uInt64 nRead, nLeft = aStatus.getFileSize(), nToRead; - - Sequence < sal_Int8 > aBuffer ( n_ConstBufferSize ); - do - { - nToRead = nLeft < n_ConstBufferSize ? nLeft : n_ConstBufferSize; - aRC = pFile->read ( static_cast < void* > ( aBuffer.getArray() ), nToRead, nRead ); -#ifdef MTG_DEBUG - fprintf ( stderr, "MTG:file read returned %d\n", aRC ); -#endif - if ( aRC != FileBase::E_None ) - { - if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, sFullPath ) ) - return e_Aborted; - } - else - { - Sequence < sal_Int8 > aReadBuf ( aBuffer.getConstArray(), static_cast < sal_Int32 > ( nRead ) ); - nLeft -= nRead; - xTempOut->writeBytes ( aReadBuf ); - if (nLeft == 0) - eRet = checkEnd ( aReadBuf ) ? e_Finished : e_Success; - } - } - while (nLeft > 0 ); - - aRC = pFile->close (); - delete pFile; - return eRet; -} - sal_Bool SAL_CALL ZipPackage::hasPendingChanges( ) throw(RuntimeException) { @@ -1339,7 +1033,7 @@ sal_Bool SAL_CALL ZipPackage::hasPendingChanges( ) Sequence< ElementChange > SAL_CALL ZipPackage::getPendingChanges( ) throw(RuntimeException) { - return Sequence < ElementChange > ( NULL, 0 ); + return Sequence < ElementChange > (); } /** @@ -1352,7 +1046,7 @@ Reference < XInterface >SAL_CALL ZipPackage_createInstance( return Reference< XInterface >( *new ZipPackage(xMgr) ); } -OUString ZipPackage::getImplementationName() +OUString ZipPackage::static_getImplementationName() { #if SUPD>625 return OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.comp.ZipPackage" ) ); @@ -1361,27 +1055,39 @@ OUString ZipPackage::getImplementationName() #endif } -Sequence< OUString > ZipPackage::getSupportedServiceNames() +Sequence< OUString > ZipPackage::static_getSupportedServiceNames() { Sequence< OUString > aNames(1); -#if SUPD>625 - aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.comp.ZipPackage" ) ); -#else - aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.package.Package" ) ); -#endif + aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.packages.Package" ) ); return aNames; } +sal_Bool SAL_CALL ZipPackage::static_supportsService( OUString const & rServiceName ) +{ + return rServiceName == getSupportedServiceNames()[0]; +} + +OUString ZipPackage::getImplementationName() + throw (RuntimeException) +{ + return static_getImplementationName(); +} + +Sequence< OUString > ZipPackage::getSupportedServiceNames() + throw (RuntimeException) +{ + return static_getSupportedServiceNames(); +} sal_Bool SAL_CALL ZipPackage::supportsService( OUString const & rServiceName ) throw (RuntimeException) { - return rServiceName == getSupportedServiceNames()[0]; + return static_supportsService ( rServiceName ); } Reference < XSingleServiceFactory > ZipPackage::createServiceFactory( Reference < XMultiServiceFactory > const & rServiceFactory ) { return cppu::createSingleFactory (rServiceFactory, - getImplementationName(), + static_getImplementationName(), ZipPackage_createInstance, - getSupportedServiceNames()); + static_getSupportedServiceNames()); } // XUnoTunnel @@ -1441,17 +1147,18 @@ Any SAL_CALL ZipPackage::getPropertyValue( const OUString& PropertyName ) aAny <<= aEncryptionKey; return aAny; } - else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "SegmentSize" ) ) ) + else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "HasEncryptedEntries" ) ) ) { - aAny <<= nSegmentSize; + aAny <<= bHasEncryptedEntries; return aAny; } - if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "HasEncryptedEntries" ) ) ) + else if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "SegmentSize" ) ) ) { - aAny <<= bHasEncryptedEntries; + aAny <<= nSegmentSize; return aAny; } - throw UnknownPropertyException(); + else + throw UnknownPropertyException(); } void SAL_CALL ZipPackage::addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException) @@ -1469,6 +1176,7 @@ void SAL_CALL ZipPackage::removeVetoableChangeListener( const OUString& Property throw(UnknownPropertyException, WrappedTargetException, RuntimeException) { } + void ZipPackage::getInteractionHandler() { if ( ! xInteractionHandler.is() ) @@ -1700,3 +1408,329 @@ sal_Bool ZipPackage::checkEnd ( Sequence < sal_Int8 > &rSequence ) } return sal_False; } +sal_Int32 ZipPackage::RequestDisk ( OUString &rMountPath, sal_Int16 nDiskNum) +{ + VolumeInfo aInfo ( osl_VolumeInfo_Mask_FreeSpace | osl_VolumeInfo_Mask_DeviceHandle | osl_VolumeInfo_Mask_Attributes ); + VolumeDevice aDevice; + FileBase::RC aRC; + + do + { + aRC = Directory::getVolumeInfo ( rMountPath, aInfo ); +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG: Requesting disk for %s, result is %d\n", ImplGetChars ( rMountPath ), aRC ); +#endif + if ( aRC == FileBase::E_None ) + aDevice = aInfo.getDeviceHandle(); + else + { +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG: Requesting disk calling HandleError with osl_File_E_INVAL\n" ); +#endif + if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, rMountPath) ) + return -1; + } + } + while ( aRC != FileBase::E_None ); +#ifdef UNX + do + { + aRC = aDevice.unmount(); +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG: unmount returned %d\n", aRC ); +#endif + if ( aRC != FileBase::E_None ) + { + if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, rMountPath) ) + return -1; + } + } + while ( aRC != FileBase::E_None ); +#endif + + Any aExceptionAny, aMediumException; + InteractiveWrongMediumException aException; + aMediumException <<= static_cast < sal_Int16 > (nDiskNum-1); + aException.Medium = aMediumException; + aExceptionAny <<= aException; + if ( !HandleError ( aExceptionAny, EC_YES|EC_ABORT ) ) + return -1; +#ifdef UNX + do + { + aRC = aDevice.automount(); + +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG: automount returned %d\n", aRC ); +#endif + if ( aRC != FileBase::E_None ) + { + if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, rMountPath) ) + return -1; + } + } + while ( aRC != FileBase::E_None ); + OUString aNewMountPath ( aDevice.getMountPath() ); + + if (aNewMountPath != rMountPath) + rMountPath = aNewMountPath; +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG: returning, new mountpath is %s\n", ImplGetChars ( rMountPath ) ); +#endif +#endif + return FileBase::E_None; +} +SegmentEnum ZipPackage::writeSegment ( const OUString &rFileName, OUString &rMountPath, Reference < XInputStream > &xInBuffer, const sal_Int16 nDiskNum ) +{ + File *pFile = NULL; + FileBase::RC aRC; + sal_Bool bDynamicSpan = nSegmentSize < 0; + Sequence < sal_Int8 > aBuffer; + + sal_Int32 nRead = n_ConstBufferSize; + sal_uInt64 nLeft, nWritten; + VolumeInfo aInfo ( osl_VolumeInfo_Mask_FreeSpace | osl_VolumeInfo_Mask_DeviceHandle | osl_VolumeInfo_Mask_Attributes ); + +#ifdef MTG_DEBUG + fprintf (stderr, "MTG: In writeSegment, disk num is %d, file is %s, dir is %s\n", + nDiskNum, ImplGetChars(rFileName), ImplGetChars(rMountPath)); +#endif + do + { + aRC = Directory::getVolumeInfo ( rMountPath, aInfo ); +#ifdef MTG_DEBUG + fprintf(stderr, "MTG: getVolumeInfo returned %d\n", aRC ); +#endif + // return value is not useful, so we check if we have valid attributes instead + if ( aInfo.isValid ( osl_VolumeInfo_Mask_FreeSpace) ) + { + sal_Bool bReCheck; + OUStringBuffer aBuffer; + aBuffer.append ( rMountPath ); + if ( rMountPath.lastIndexOf ( '/' ) != rMountPath.getLength()-1 ) + aBuffer.appendAscii ( "/" ); + aBuffer.append ( rFileName ); + OUString sFullPath ( aBuffer.makeStringAndClear() ); + do + { + bReCheck = sal_False; + sal_uInt64 nFree = aInfo.getFreeSpace(); +#ifdef MTG_DEBUG + fprintf(stderr, "MTG: free is %d\n", static_cast < sal_Int32 > ( nFree ) ); +#endif + if ( ( bDynamicSpan && nFree < 1000 ) || + ( !bDynamicSpan && nFree < nSegmentSize ) ) + { + if ( !HandleError ( osl_File_E_NOSPC, EC_RETRY|EC_ABORT, sFullPath ) ) + { + if ( pFile ) + delete pFile; + return e_Aborted; + } + else + { + aRC = Directory::getVolumeInfo ( rMountPath, aInfo ); + bReCheck = sal_True; + } + } + else + { + nLeft = bDynamicSpan ? nFree : nSegmentSize; +#ifdef MTG_DEBUG + fprintf(stderr, "MTG: left is %ld\n", static_cast < sal_Int32 > ( nLeft ) ); +#endif + } + } + while ( bReCheck ); +#ifdef MTG_DEBUG + fprintf( stderr, "MTG: sDirectoryName is %s sFileName is %s FullPath is %s\n", + ImplGetChars ( rMountPath ), ImplGetChars ( rFileName ), ImplGetChars ( sFullPath ) ); +#endif + pFile = new File ( sFullPath ); + sal_Bool bExists = sal_False; + aRC = pFile->open ( osl_File_OpenFlag_Create | osl_File_OpenFlag_Write ); + if ( aRC == FileBase::E_EXIST ) + { + aRC = pFile->open ( osl_File_OpenFlag_Write ); + bExists = sal_True; + } + if ( aRC != FileBase::E_None ) + { +#ifdef MTG_DEBUG + fprintf(stderr, "MTG: file open returned %d\n", aRC ); +#endif + if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, sFullPath ) ) + { + delete pFile; + return e_Aborted; + } + } + else if ( bExists ) + { + // Truncate to 0 if necessary + aRC = pFile->setSize ( 0 ); + } + } + else + { + aRC = FileBase::E_IO; + if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, rMountPath ) ) + return e_Aborted; + } + } + while (aRC != FileBase::E_None ); + + // Now! We should have an open file on a disk which has at least nSegmentSize if not + // dynamic spanning and 1000 bytes if dynamic spanning. + + + // Let's read it all into the buffer in case something goes wrong and also + // so that the spannable checks in ByteChucker and ZipOutputStream work + + nRead = xInBuffer->readBytes ( aBuffer, static_cast < sal_Int32 > ( nLeft ) ); + + aRC = pFile->write ( aBuffer.getConstArray(), nRead, nWritten ); +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG: write returned %d\n", aRC ); +#endif + + sal_Bool bRetry = sal_False; + + if ( nWritten != nRead || aRC != FileBase::E_None ) + bRetry = sal_True; + else + { + aRC = pFile->close (); +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG: close returned %d\n", aRC ); +#endif + if ( aRC != FileBase::E_None ) + bRetry = sal_True; + } + delete pFile; + return nRead < nLeft ? e_Finished : bRetry ? e_Retry : e_Success; +} + +SegmentEnum ZipPackage::writeSegment ( const OUString &rFileName, Reference < XInputStream > &xInBuffer ) +{ + FileBase::RC aRC; + Sequence < sal_Int8 > aBuffer ( nSegmentSize ); + + sal_uInt64 nWritten; + + sal_Int32 nRead = xInBuffer->readBytes ( aBuffer, static_cast < sal_Int32 > ( nSegmentSize ) ); + + File aFile ( rFileName ); + aRC = aFile.open ( osl_File_OpenFlag_Create | osl_File_OpenFlag_Write ); + sal_Bool bExists = sal_False; + if ( aRC == FileBase::E_EXIST ) + { + aRC = aFile.open ( osl_File_OpenFlag_Write ); + bExists = sal_True; + } + if ( aRC != FileBase::E_None ) + { + if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, rFileName ) ) + return e_Aborted; + } + else if ( bExists ) + { + // truncate if necessary + aFile.setSize ( 0 ); + } + + aRC = aFile.write ( aBuffer.getConstArray(), nRead, nWritten ); +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG: write returned %d\n", aRC ); +#endif + + sal_Bool bRetry = sal_False; + if ( nWritten != nRead || aRC != FileBase::E_None ) + bRetry = sal_True; + else + { + aRC = aFile.close (); +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG: close returned %d\n", aRC ); +#endif + if ( aRC != FileBase::E_None ) + bRetry = sal_True; + } + return nRead < nSegmentSize ? e_Finished : bRetry ? e_Retry : e_Success; +} + +SegmentEnum ZipPackage::readSegment ( const OUString &rFileName, OUString &rMountPath, Reference < XOutputStream > &xTempOut, const sal_Int16 nDiskNum ) +{ + File *pFile = NULL; + FileBase::RC aRC; + SegmentEnum eRet; + + OUStringBuffer aStringBuffer; + aStringBuffer.append ( rMountPath ); + if ( rMountPath.lastIndexOf ( '/' ) != rMountPath.getLength()-1 ) + aStringBuffer.appendAscii ( "/" ); + aStringBuffer.append ( rFileName ); + OUString sFullPath ( aStringBuffer.makeStringAndClear() ); + +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG: trying to read %s\n", ImplGetChars ( sFullPath ) ); +#endif + DirectoryItem aItem; + do + { + aRC = DirectoryItem::get ( sFullPath, aItem ); +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG: DirectoryItem::get returned %d\n", aRC ); +#endif + if ( aRC != FileBase::E_None && !HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, sFullPath ) ) + return e_Aborted; + } + while (aRC != FileBase::E_None ); + do + { + pFile = new File ( sFullPath ); + aRC = pFile->open ( osl_File_OpenFlag_Read ); +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG:file open returned %d\n", aRC ); +#endif + if ( aRC != FileBase::E_None ) + { + delete pFile; + if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, sFullPath ) ) + return e_Aborted; + } + } + while (aRC != FileBase::E_None ); + + FileStatus aStatus ( FileStatusMask_FileSize ); + aItem.getFileStatus ( aStatus ); + sal_uInt64 nRead, nLeft = aStatus.getFileSize(), nToRead; + + Sequence < sal_Int8 > aBuffer ( n_ConstBufferSize ); + do + { + nToRead = nLeft < n_ConstBufferSize ? nLeft : n_ConstBufferSize; + aRC = pFile->read ( static_cast < void* > ( aBuffer.getArray() ), nToRead, nRead ); +#ifdef MTG_DEBUG + fprintf ( stderr, "MTG:file read returned %d\n", aRC ); +#endif + if ( aRC != FileBase::E_None ) + { + if ( ! HandleError ( (oslFileError) aRC, EC_RETRY|EC_ABORT, sFullPath ) ) + return e_Aborted; + } + else + { + Sequence < sal_Int8 > aReadBuf ( aBuffer.getConstArray(), static_cast < sal_Int32 > ( nRead ) ); + nLeft -= nRead; + xTempOut->writeBytes ( aReadBuf ); + if (nLeft == 0) + eRet = checkEnd ( aReadBuf ) ? e_Finished : e_Success; + } + } + while (nLeft > 0 ); + + aRC = pFile->close (); + delete pFile; + return eRet; +} |