INTEGRATION: CWS mav09 (1.137.42); FILE MERGED
2004/09/16 23:53:59 mav 1.137.42.28: RESYNC: (1.140-1.141); FILE MERGED
2004/09/10 13:48:03 mav 1.137.42.27: #i27773# check for itemset existence
2004/09/03 15:04:22 mba 1.137.42.26: #i27773#: Medium shouldn't be closed while loading, SFX will do it for readonly files after loading
2004/08/27 07:06:36 mav 1.137.42.25: #i27773# close medium input and output stream completely
2004/08/25 11:35:56 mav 1.137.42.24: #i27773# document storage related problems
2004/08/23 07:52:19 mav 1.137.42.23: #i27773# readjust todo's
2004/08/16 15:50:26 mav 1.137.42.22: #i27773# include
2004/08/16 15:48:50 mav 1.137.42.21: #i27773# resolve ambiguity
2004/08/13 11:41:55 mav 1.137.42.20: #i27773# do not overwrite if the related property is set to false
2004/07/15 11:07:54 mav 1.137.42.19: #i27773# commit changes made offline
2004/07/15 10:55:40 mba 1.137.42.18: #i27773#: cleaning up todos
2004/07/07 17:22:18 mav 1.137.42.17: RESYNC: (1.139-1.140); FILE MERGED
2004/07/06 14:16:14 mav 1.137.42.16: #i27773# review and solve some TODOs
2004/07/05 11:54:59 mav 1.137.42.15: #i27773# package repairing
2004/07/02 16:37:19 mba 1.137.42.14: #i27773#: merge conflicts
2004/07/02 08:39:36 mba 1.137.42.13: #i27773#: some TODOs
2004/06/01 10:29:34 mav 1.137.42.12: #i27773# let streams be closed when requested
2004/06/01 08:15:25 mba 1.137.42.11: #i27773#: new storage API
2004/05/28 13:09:18 mav 1.137.42.10: #i27773# create medium in truncate mode, truncate target stream on writing
2004/05/28 10:14:54 mba 1.137.42.9: #27773#: make sure that non existing files don't disturb saving
2004/05/28 09:15:44 mav 1.137.42.8: #i27773# SaveAs to the same file
2004/05/18 16:23:52 mav 1.137.42.7: #i27773# resolve resync problems
2004/05/10 08:18:17 mba 1.137.42.6: #i27773#: notification of UIActivation fixed; some bugfixes; added support for replacement images
2004/05/06 13:02:14 mba 1.137.42.5: #i27773#: wrong assertions
2004/05/04 15:14:44 mba 1.137.42.4: #i27773#: sharing storages
2004/05/04 13:02:13 mba 1.137.42.3: #i27773#: remove so3
2004/04/29 21:21:16 mav 1.137.42.2: RESYNC: (1.137-1.139); FILE MERGED
2004/04/14 11:46:09 mba 1.137.42.1: #i27773#: use new storage API; remove SO3
diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 6673f28..89ee4d6 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: docfile.cxx,v $
*
* $Revision: 1.141 $
* $Revision: 1.142 $
*
* last change: $Author: kz $ $Date: 2004-08-31 12:35:02 $
* last change: $Author: kz $ $Date: 2004-10-04 20:53:11 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -65,6 +65,15 @@
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/ucb/XContent.hpp>
#ifndef _COM_SUN_STAR_EMBED_XTRANSACTEDOBJECT_HPP_
#include <com/sun/star/embed/XTransactedObject.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_USEBACKUPEXCEPTION_HPP_
#include <com/sun/star/embed/UseBackupException.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_INTERACTIVEIOEXCEPTION_HPP_
#include <com/sun/star/ucb/InteractiveIOException.hpp>
#endif
@@ -95,6 +104,9 @@
#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XTRUNCATE_HPP_
#include <com/sun/star/io/XTruncate.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XSTREAMLISTENER_HPP_
#include <com/sun/star/io/XStreamListener.hpp>
#endif
@@ -122,6 +134,9 @@
#ifndef _COM_SUN_STAR_UCB_OPENMODE_HPP_
#include <com/sun/star/ucb/OpenMode.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_NAMECLASHEXCEPTION_HPP_
#include <com/sun/star/ucb/NameClashException.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
@@ -159,9 +174,6 @@
#ifndef _MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SVSTOR_HXX //autogen
#include <so3/svstor.hxx>
#endif
#ifndef _EXTATTR_HXX
#include <svtools/extattr.hxx>
#endif
@@ -192,6 +204,8 @@
#define _SVSTDARR_STRINGSDTOR
#include <svtools/svstdarr.hxx>
#include <unotools/streamwrap.hxx>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
@@ -202,8 +216,9 @@ using namespace ::com::sun::star::io;
#pragma hdrstop
#endif
#include <comphelper/processfactory.hxx>
#include <so3/transbnd.hxx> // SvKeyValueIterator
#include <comphelper/storagehelper.hxx>
#include <comphelper/mediadescriptor.hxx>
//#include <so3/transbnd.hxx> // SvKeyValueIterator
#include <tools/urlobj.hxx>
#include <tools/inetmime.hxx>
#include <unotools/ucblockbytes.hxx>
@@ -232,71 +247,12 @@ using namespace ::com::sun::star::io;
#include "doc.hrc" // MSG_WARNING_BACKUP, MSG_OPEN_READONLY
#include "openflag.hxx" // SFX_STREAM_READONLY etc.
#include "sfxresid.hxx"
#include "appuno.hxx"
#include "xmlversion.hxx"
#define MAX_REDIRECT 5
class SfxLockBytesHandler_Impl : public ::utl::UcbLockBytesHandler
{
ULONG m_nAcquireCount;
SfxMedium* m_pMedium;
::vos::OMutex m_aMutex;
public:
SfxLockBytesHandler_Impl( SfxMedium* pMedium )
: m_nAcquireCount( 0 )
, m_pMedium( pMedium )
{}
virtual void Handle( ::utl::UcbLockBytesHandler::LoadHandlerItem nWhich, ::utl::UcbLockBytesRef xLockBytes );
::vos::OMutex& GetMutex()
{ return m_aMutex; }
void ReleaseMedium()
{ m_pMedium = NULL; }
};
SV_DECL_IMPL_REF( SfxLockBytesHandler_Impl );
void SfxLockBytesHandler_Impl::Handle( ::utl::UcbLockBytesHandler::LoadHandlerItem nWhich, ::utl::UcbLockBytesRef xLockBytes )
{
::vos::OGuard aGuard( m_aMutex );
if ( IsActive() && xLockBytes.Is()&& m_pMedium )
{
switch( nWhich )
{
case DATA_AVAILABLE :
m_pMedium->DataAvailable_Impl();
break;
case DONE :
m_pMedium->Done_Impl( xLockBytes->GetError() );
break;
case CANCEL :
m_pMedium->Cancel_Impl();
break;
default:
break;
}
}
}
class UcbLockBytesCancellable_Impl : public SfxCancellable
{
::utl::UcbLockBytesRef xLockBytes;
public:
UcbLockBytesCancellable_Impl( const ::utl::UcbLockBytesRef& rLockBytes, SfxCancelManager* pManager, const String& rTitle )
: SfxCancellable( pManager, rTitle )
, xLockBytes( rLockBytes )
{}
virtual void Cancel();
};
void UcbLockBytesCancellable_Impl::Cancel()
{
xLockBytes->Cancel();
}
class SfxMediumHandler_Impl : public ::cppu::WeakImplHelper1< com::sun::star::task::XInteractionHandler >
{
com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInter;
@@ -400,15 +356,15 @@ public:
sal_Bool bDontCreateCancellable : 1;
sal_Bool bDownloadDone : 1;
sal_Bool bDontCallDoneLinkOnSharingError : 1;
sal_Bool bStreamReady: 1;
sal_Bool bIsStorage: 1;
sal_Bool bUseInteractionHandler: 1;
sal_Bool bAllowDefaultIntHdl: 1;
sal_Bool bIsDiskSpannedJAR: 1;
sal_Bool bIsCharsetInitialized: 1;
sal_Bool bDisposeStorage: 1;
uno::Reference < embed::XStorage > xStorage;
SfxPoolCancelManagerRef xCancelManager;
UcbLockBytesCancellable_Impl* pCancellable;
SfxMedium* pAntiImpl;
SvEaMgr* pEaMgr;
@@ -424,14 +380,13 @@ public:
svtools::AsynchronLink aDoneLink;
svtools::AsynchronLink aAvailableLink;
SfxLockBytesHandler_ImplRef aHandler;
SfxVersionTableDtor* pVersions;
::utl::TempFile* pTempDir;
::utl::TempFile* pTempFile;
Reference < XInputStream > xInputStream;
::utl::UcbLockBytesRef xLockBytes;
Reference < XStream > xStream;
sal_uInt32 nLastStorageError;
::rtl::OUString aCharset;
@@ -447,21 +402,6 @@ public:
~SfxMedium_Impl();
};
void SfxMedium::Done_Impl( ErrCode nError )
{
DELETEZ( pImp->pCancellable );
pImp->bDownloadDone = sal_True;
SetError( nError );
if ( pImp->xLockBytes.Is() )
pImp->xInputStream = pImp->xLockBytes->getInputStream();
if ( ( !nError || !pImp->bDontCallDoneLinkOnSharingError ) && ( pImp->bStreamReady || !pInStream ) )
{
pImp->aDoneLink.ClearPendingCall();
pImp->aDoneLink.Call( (void*) nError );
}
}
void SfxMedium::DataAvailable_Impl()
{
pImp->aAvailableLink.ClearPendingCall();
@@ -494,9 +434,8 @@ SfxMedium_Impl::SfxMedium_Impl( SfxMedium* pAntiImplP )
:
SvCompatWeakBase( pAntiImplP ),
bUpdatePickList(sal_True), bIsTemp( sal_False ), pOrigFilter( 0 ),
pCancellable( 0 ),
aExpireTime( Date() + 10, Time() ),
bForceSynchron( sal_False ), bStreamReady( sal_False ), bIsStorage( sal_False ),
bForceSynchron( sal_False ), bIsStorage( sal_False ),
pAntiImpl( pAntiImplP ),
bDontCreateCancellable( sal_False ), pTempDir( NULL ), bIsDiskSpannedJAR( sal_False ),
bDownloadDone( sal_True ), bDontCallDoneLinkOnSharingError( sal_False ),nFileVersion( 0 ), pEaMgr( NULL ), pTempFile( NULL ),
@@ -506,17 +445,12 @@ SfxMedium_Impl::SfxMedium_Impl( SfxMedium* pAntiImplP )
bAllowDefaultIntHdl( sal_False ),
m_bRemoveBackup( sal_False )
{
aHandler = new SfxLockBytesHandler_Impl( pAntiImpl );
aDoneLink.CreateMutex();
}
//------------------------------------------------------------------
SfxMedium_Impl::~SfxMedium_Impl()
{
delete pCancellable;
if ( aHandler.Is() )
aHandler->Activate( sal_False );
aDoneLink.ClearPendingCall();
aAvailableLink.ClearPendingCall();
@@ -547,6 +481,7 @@ SfxMedium_Impl::~SfxMedium_Impl()
pOutStream( 0 )
//------------------------------------------------------------------
/*
const SvGlobalName& SfxMedium::GetClassFilter()
{
GetMedium_Impl();
@@ -555,14 +490,12 @@ const SvGlobalName& SfxMedium::GetClassFilter()
if( !bSetFilter && GetStorage() )
SetClassFilter( GetStorage()->GetClassName() );
return aFilterClass;
}
}*/
//------------------------------------------------------------------
void SfxMedium::ResetError()
{
eError = SVSTREAM_OK;
if( aStorage.Is() )
aStorage->ResetError();
if( pInStream )
pInStream->ResetError();
if( pOutStream )
@@ -583,8 +516,6 @@ sal_uInt32 SfxMedium::GetErrorCode() const
lError=pInStream->GetErrorCode();
if(!lError && pOutStream)
lError=pOutStream->GetErrorCode();
if(!lError && aStorage.Is())
lError=aStorage->GetErrorCode();
return lError;
}
@@ -680,8 +611,13 @@ SvStream* SfxMedium::GetInStream()
GetMedium_Impl();
if ( !pInStream && eError == ERRCODE_IO_PENDING )
eError = SVSTREAM_OK;
if ( GetError() )
return NULL;
if ( pImp->xStream.is() )
pInStream = utl::UcbStreamHelper::CreateStream( pImp->xStream );
else if ( pImp->xInputStream.is() )
pInStream = utl::UcbStreamHelper::CreateStream( pImp->xInputStream );
return pInStream;
}
@@ -697,22 +633,38 @@ void SfxMedium::CloseInStream_Impl()
// if there is a storage based on the InStream, we have to
// close the storage, too, because otherwise the storage
// would use an invalid ( deleted ) stream.
if ( pInStream && aStorage.Is() )
if ( pInStream && pImp->xStorage.is() )
{
const SvStream *pStorage = aStorage->GetSvStream();
if ( pStorage == pInStream )
//TODO/MBA: how to deal with this?!
//maybe we need a new flag when the storage was created from the instream
//const SvStream *pStorage = aStorage->GetSvStream();
//if ( pStorage == pInStream )
{
CloseStorage();
}
}
if ( pInStream && !GetContent().is() )
{
CreateTempFile();
return;
}
DELETEZ( pInStream );
pImp->xInputStream = Reference < XInputStream >();
pImp->xLockBytes.Clear();
//pImp->xInputStream = Reference < XInputStream >();
//pImp->xLockBytes.Clear();
if ( pSet )
pSet->ClearItem( SID_INPUTSTREAM );
DELETEZ( pImp->pCancellable );
pImp->xInputStream = uno::Reference< io::XInputStream >();
if ( !pOutStream )
{
// output part of the stream is not used so the whole stream can be closed
// TODO/LATER: is it correct?
pImp->xStream = uno::Reference< io::XStream >();
if ( pSet )
pSet->ClearItem( SID_STREAM );
}
}
//------------------------------------------------------------------
@@ -749,10 +701,12 @@ sal_Bool SfxMedium::CloseOutStream_Impl()
// if there is a storage based on the OutStream, we have to
// close the storage, too, because otherwise the storage
// would use an invalid ( deleted ) stream.
if ( aStorage.Is() )
//TODO/MBA: how to deal with this?!
//maybe we need a new flag when the storage was created from the outstream
if ( pImp->xStorage.is() )
{
const SvStream *pStorage = aStorage->GetSvStream();
if ( pStorage == pOutStream )
//const SvStream *pStorage = aStorage->GetSvStream();
//if ( pStorage == pOutStream )
CloseStorage();
}
@@ -760,6 +714,15 @@ sal_Bool SfxMedium::CloseOutStream_Impl()
pOutStream = NULL;
}
if ( !pInStream )
{
// input part of the stream is not used so the whole stream can be closed
// TODO/LATER: is it correct?
pImp->xStream = uno::Reference< io::XStream >();
if ( pSet )
pSet->ClearItem( SID_STREAM );
}
return sal_True;
}
@@ -790,12 +753,8 @@ void SfxMedium::CreateFileStream()
//------------------------------------------------------------------
sal_Bool SfxMedium::Commit()
{
if( aStorage.Is() )
{
// StorageStream immer direkt
if( !aStorage->Commit() )
eError = aStorage->GetError();
}
if( pImp->xStorage.is() )
StorageCommit_Impl();
else if( pOutStream )
pOutStream->Flush();
else if( pInStream )
@@ -812,7 +771,7 @@ sal_Bool SfxMedium::Commit()
//------------------------------------------------------------------
sal_Bool SfxMedium::IsStorage()
{
if ( aStorage.Is() )
if ( pImp->xStorage.is() )
return TRUE;
if ( bTriedStorage )
@@ -823,13 +782,13 @@ sal_Bool SfxMedium::IsStorage()
String aURL;
if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL ) )
DBG_ERROR("Physical name not convertable!");
pImp->bIsStorage = SotStorage::IsStorageFile( aURL );
pImp->bIsStorage = SotStorage::IsStorageFile( aURL ) && !SotStorage::IsOLEStorage( aURL);
if ( !pImp->bIsStorage )
bTriedStorage = TRUE;
}
else if ( GetInStream() )
{
pImp->bIsStorage = SotStorage::IsStorageFile( pInStream );
pImp->bIsStorage = SotStorage::IsStorageFile( pInStream ) && !SotStorage::IsOLEStorage( pInStream );
if ( !pInStream->GetError() && !pImp->bIsStorage )
bTriedStorage = TRUE;
}
@@ -876,7 +835,7 @@ sal_Bool SfxMedium::TryStorage()
{
GetStorage();
if ( aStorage.Is() )
if ( pImp->xStorage.is() )
return sal_True;
// this code will be removed when binary filter components are available!
@@ -930,147 +889,210 @@ sal_Bool SfxMedium::TryStorage()
SetPhysicalName_Impl( aTemp );
GetStorage();
if ( aStorage.Is() )
{
const SfxFilter *pRealFilter = SFX_APP()->GetFilterMatcher().GetFilter4ClipBoardId( aStorage->GetFormat() );
if ( pRealFilter )
{
pImp->nFileVersion = pRealFilter->GetVersion();
aStorage->SetVersion( pImp->nFileVersion );
}
return pImp->xStorage.is();
}
DBG_ASSERT( pRealFilter, "Unknown storage format!" );
void SfxMedium::StorageBackup_Impl()
{
::ucb::Content aOriginalContent;
Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
if ( !pImp->pTempFile && !pImp->m_aBackupURL.getLength()
&& GetURLObject().GetMainURL( INetURLObject::NO_DECODE ).Len()
&& ::utl::LocalFileHelper::IsLocalFile( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
&& ::utl::UCBContentHelper::IsDocument( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) )
&& ::ucb::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv, aOriginalContent ) )
{
DoInternalBackup_Impl( aOriginalContent );
if( !pImp->m_aBackupURL.getLength() )
{
// TODO/LATER: move the message to the interaction handler
WarningBox( NULL, SfxResId( MSG_WARNING_BACKUP ) ).Execute();
SetError( ERRCODE_ABORT );
}
}
}
::rtl::OUString SfxMedium::GetOutputStorageURL_Impl()
{
String aStorageName;
if ( aName.Len() )
{
if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aStorageName ) )
{
DBG_ERROR("Physical name not convertable!");
}
}
else
{
aStorageName = GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
}
return aStorage.Is();
return sal_False;
return aStorageName;
}
//------------------------------------------------------------------
SvStorage* SfxMedium::GetOutputStorage( BOOL bUCBStorage )
uno::Reference < embed::XStorage > SfxMedium::GetOutputStorage()
{
// if the medium was constructed with a SvStorage: use this one, not a temp. storage
if ( aStorage.Is() && !aLogicName.Len() )
return aStorage;
if ( GetError() )
return uno::Reference< embed::XStorage >();
if ( !pImp->pTempFile )
// if the medium was constructed with a Storage: use this one, not a temp. storage
if ( pImp->xStorage.is() && !aLogicName.Len() )
return pImp->xStorage;
// if necessary close stream that was used for reading
if ( pInStream && !pInStream->IsWritable() )
CloseInStream();
DBG_ASSERT( !pOutStream, "OutStream in a readonly Medium?!" );
// medium based on OutputStream: must work with TempFile
USHORT nState = GetItemSet()->GetItemState( SID_STREAM );
if( aLogicName.CompareToAscii( "private:stream", 14 ) == COMPARE_EQUAL )
CreateTempFile();
return GetStorage_Impl( bUCBStorage );
// if Medium already contains a stream - TODO/LATER: store stream/outputstream in ImplData, not in Medium
else if ( GetItemSet()->GetItemState( SID_STREAM ) < SFX_ITEM_SET )
{
// check whether the backup should be created
StorageBackup_Impl();
if ( GetError() )
return uno::Reference< embed::XStorage >();
// the target file must be truncated before a storage based on it is created
try {
uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess(
xFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess") ),
uno::UNO_QUERY_THROW );
SFX_ITEMSET_ARG( GetItemSet(), pOverWrite, SfxBoolItem, SID_OVERWRITE, sal_False );
SFX_ITEMSET_ARG( GetItemSet(), pRename, SfxBoolItem, SID_RENAME, sal_False );
sal_Bool bRename = pRename ? pRename->GetValue() : FALSE;
sal_Bool bOverWrite = pOverWrite ? pOverWrite->GetValue() : !bRename;
::rtl::OUString aOutputURL = GetOutputStorageURL_Impl();
// TODO/LATER: not an atomar operation
if ( !bOverWrite && xSimpleFileAccess->exists( aOutputURL ) )
throw ::com::sun::star::ucb::NameClashException();
uno::Reference< io::XStream > xStream =
xSimpleFileAccess->openFileReadWrite( aOutputURL );
uno::Reference< io::XOutputStream > xOutStream = xStream->getOutputStream();
uno::Reference< io::XTruncate > xTruncate( xOutStream, uno::UNO_QUERY );
if ( !xTruncate.is() )
throw uno::RuntimeException();
xTruncate->truncate();
xOutStream->flush();
pImp->xStream = xStream;
GetItemSet()->Put( SfxUsrAnyItem( SID_STREAM, makeAny( xStream ) ) );
}
catch( uno::Exception& )
{
DBG_ERROR( "Can't truncate target stream!\n" );
SetError( ERRCODE_IO_GENERAL );
}
}
return GetStorage();
}
SvStorage* SfxMedium::GetStorage()
uno::Reference < embed::XStorage > SfxMedium::GetStorage()
{
return GetStorage_Impl( pFilter && SOFFICE_FILEFORMAT_60 <= pFilter->GetVersion() );
}
SvStorage* SfxMedium::GetStorage_Impl( BOOL bUCBStorage )
{
if ( aStorage.Is() || bTriedStorage )
return aStorage;
if ( pImp->xStorage.is() || bTriedStorage )
return pImp->xStorage;
String aStorageName;
if ( pImp->pTempFile || pImp->pTempDir )
{
// open storage with the URL of the tempfile
if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aStorageName ) )
{
DBG_ERROR("Physical name not convertable!");
}
CloseOutStream();
aStorage = new SvStorage( bUCBStorage, aStorageName, nStorOpenMode, bDirect ? 0 : STORAGE_TRANSACTED );
pImp->xStorage = comphelper::OStorageHelper::GetStorageFromURL( pImp->pTempFile->GetURL(), nStorOpenMode&STREAM_WRITE ?
embed::ElementModes::READWRITE : embed::ElementModes::READ );
}
else
{
if ( aName.Len() )
{
if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aStorageName ) )
{
DBG_ERROR("Physical name not convertable!");
}
}
else
aStorageName = GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
GetMedium_Impl();
if ( GetError() )
return pImp->xStorage;
GetInStream();
if ( pInStream )
{
pInStream->GetLockBytes()->SetSynchronMode( sal_True );
if( UCBStorage::IsDiskSpannedFile( pInStream ) )
try
{
// packed remote files can't be opened outside the storage, so they must be reopened
// inside the storage even if it is expensive
pImp->bIsDiskSpannedJAR = TRUE;
CloseInStream();
aStorage = new SvStorage( TRUE, aStorageName, nStorOpenMode, bDirect ? 0 : STORAGE_TRANSACTED );
SfxFilterFlags nMust = SFX_FILTER_IMPORT, nDont = SFX_FILTER_NOTINSTALLED | SFX_FILTER_STARONEFILTER;
SetFilter( SFX_APP()->GetFilterMatcher().GetFilter4ClipBoardId( aStorage->GetFormat(), nMust, nDont ) );
}
else
{
// download the stream ( or at least start the download )
if ( !pImp->aDoneLink.IsSet() )
DownLoad();
uno::Sequence< uno::Any > aArgs( 2 );
sal_Int32 nArgsLen = 2;
if ( IsReadOnly() && ::utl::LocalFileHelper::IsLocalFile( aLogicName ) )
{
//TODO/LATER: performance problem if not controlled by special Mode in SfxMedium
//(should be done only for permanently open storages)
// create a copy
CreateTempFile();
aArgs[0] <<= ::rtl::OUString( aName );
aArgs[1] <<= embed::ElementModes::READ;
}
else
{
// create a storage on the stream
if ( pImp->xStream.is() )
{
aArgs[0] <<= pImp->xStream;
aArgs[1] <<= ( ( nStorOpenMode & STREAM_WRITE ) ?
embed::ElementModes::READWRITE : embed::ElementModes::READ );
}
else
{
aArgs[0] <<= pImp->xInputStream;
aArgs[1] <<= embed::ElementModes::READ;
}
}
SFX_ITEMSET_ARG( GetItemSet(), pItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False);
if ( pItem && pItem->GetValue() )
{
// CreateTempFile();
CreateTempFile();
Reference< ::com::sun::star::ucb::XProgressHandler > xProgressHandler;
Reference< ::com::sun::star::task::XStatusIndicator > xStatusIndicator;
SFX_ITEMSET_ARG( GetItemSet(), pxProgressItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, sal_False );
if( pxProgressItem && ( pxProgressItem->GetValue() >>= xStatusIndicator ) )
xProgressHandler = Reference< ::com::sun::star::ucb::XProgressHandler >(
new utl::ProgressHandlerWrap( xStatusIndicator ) );
INetURLObject aObj( aName );
if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
{
String aURL;
::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL );
aObj.SetURL( aURL );
}
uno::Sequence< beans::PropertyValue > aAddProps( 2 );
aAddProps[0].Name = ::rtl::OUString::createFromAscii( "RepairPackage" );
aAddProps[0].Value <<= (sal_Bool)sal_True;
aAddProps[1].Name = ::rtl::OUString::createFromAscii( "StatusIndicator" );
aAddProps[1].Value <<= xProgressHandler;
UCBStorage* pUCBStorage = new UCBStorage( aObj.GetMainURL( INetURLObject::NO_DECODE ),
nStorOpenMode,
bDirect ? 0 : STORAGE_TRANSACTED,
sal_True,
sal_True,
xProgressHandler );
aStorage = new SvStorage( pUCBStorage );
aArgs.realloc( ++nArgsLen );
aArgs[nArgsLen-1] <<= aAddProps;
}
else
{
if( SotStorage::IsStorageFile( pInStream ) )
{
if ( IsReadOnly() && ::utl::LocalFileHelper::IsLocalFile( aLogicName ) )
{
CreateTempFile();
aStorage = new SvStorage( bUCBStorage, aName, nStorOpenMode, bDirect ? 0 : STORAGE_TRANSACTED );
}
else
{
if ( bUCBStorage && !UCBStorage::IsStorageFile( pInStream ) )
return NULL;
// create a storage on the stream
aStorage = new SvStorage( pInStream, sal_False );
if ( !aStorage->GetName().Len() )
aStorage->SetName( aStorageName );
}
}
else
return NULL;
}
pImp->xStorage = uno::Reference< embed::XStorage >(
::comphelper::OStorageHelper::GetStorageFactory()->createInstanceWithArguments( aArgs ),
uno::UNO_QUERY );
if ( !pImp->xStorage.is() )
throw uno::RuntimeException();
}
catch ( uno::Exception& )
{
//TODO/MBA: error handling; Error and LastStorageError
}
}
else
return NULL;
}
if( ( pImp->nLastStorageError = GetError() ) != SVSTREAM_OK )
{
aStorage.Clear();
pImp->xStorage = 0;
if ( pInStream )
pInStream->Seek(0);
return NULL;
@@ -1078,17 +1100,13 @@ SvStorage* SfxMedium::GetStorage_Impl( BOOL bUCBStorage )
bTriedStorage = sal_True;
if ( aStorage->GetError() == SVSTREAM_OK )
//TODO/MBA: error handling; Error and LastStorageError
//if ( aStorage->GetError() == SVSTREAM_OK )
{
SetStorageKey_Impl();
//SetStorageKey_Impl();
GetVersionList();
}
// ???? wird das noch gebraucht?
// GetMedium_Impl();
// if ( !aStorage.Is() )
// CreateFileStream();
SFX_ITEMSET_ARG( pSet, pVersion, SfxInt16Item, SID_VERSION, sal_False);
BOOL bResetStorage = FALSE;
@@ -1113,41 +1131,29 @@ SvStorage* SfxMedium::GetStorage_Impl( BOOL bUCBStorage )
String aVersionStream = pInfo->aName;
// SubStorage f"ur alle Versionen "offnen
SvStorageRef aSub =
aStorage->OpenStorage( DEFINE_CONST_UNICODE( "Versions" ), SFX_STREAM_READONLY | STREAM_NOCREATE );
uno::Reference < embed::XStorage > xSub = pImp->xStorage->openStorageElement( DEFINE_CONST_UNICODE( "Versions" ),
embed::ElementModes::READ );
DBG_ASSERT( aSub.Is() && !aSub->GetError(), "Versionsliste, aber keine Versionen!" );
DBG_ASSERT( xSub.is(), "Versionsliste, aber keine Versionen!" );
// Dort ist die Version als gepackter Stream gespeichert
SvStorageStreamRef aStream =
aSub->OpenStream( aVersionStream, SFX_STREAM_READONLY );
uno::Reference < io::XStream > xStr = pImp->xStorage->openStreamElement( aVersionStream,
embed::ElementModes::READ );
SvStream* pStream = utl::UcbStreamHelper::CreateStream( xStr );
if ( aStream.Is() && aStream->GetError() == SVSTREAM_OK )
if ( pStream && pStream->GetError() == SVSTREAM_OK )
{
// Stream ins TempDir auspacken
::utl::TempFile aTempFile;
String aTmpName = aTempFile.GetURL();
SvFileStream aTmpStream( aTmpName, SFX_STREAM_READWRITE );
// The new file format uses UCB storages instead of OLE storages.
// These storages aren't compressed.
if ( !aSub->IsOLEStorage() )
{
*aStream >> aTmpStream;
}
else
{
ZCodec aCodec;
aCodec.BeginCompression();
aCodec.Decompress( *aStream, aTmpStream );
aCodec.EndCompression();
}
*pStream >> aTmpStream;
aTmpStream.Close();
// Datei als Storage "offnen
nStorOpenMode = SFX_STREAM_READONLY;
aStorage = new SvStorage( aTmpName, nStorOpenMode );
pImp->xStorage = comphelper::OStorageHelper::GetStorageFromURL( aTmpName, embed::ElementModes::READ );
String aTemp;
::utl::LocalFileHelper::ConvertURLToPhysicalName( aTmpName, aTemp );
SetPhysicalName_Impl( aTemp );
@@ -1166,46 +1172,46 @@ SvStorage* SfxMedium::GetStorage_Impl( BOOL bUCBStorage )
bResetStorage = TRUE;
}
if ( aStorage.Is() )
{
//TODO/MBA: error handling; Error and LastStorageError
if ( pImp->xStorage.is() )
{ /*
if( ( pImp->nLastStorageError = aStorage->GetError() ) != SVSTREAM_OK )
bResetStorage = TRUE;
else if ( GetFilter() )
aStorage->SetVersion( GetFilter()->GetVersion() );
aStorage->SetVersion( GetFilter()->GetVersion() );*/
}
if ( bResetStorage )
{
aStorage.Clear();
pImp->xStorage = 0;
if ( pInStream )
pInStream->Seek( 0L );
}
pImp->bIsStorage = aStorage.Is();
return aStorage;
}
//------------------------------------------------------------------
sal_Bool GetPasswd_Impl( const SfxItemSet* pSet, String& rPasswd );
void SfxMedium::SetStorageKey_Impl()
{
// in case media-descriptor contains password it should be used on opening
if ( aStorage.Is() && pSet )
{
String aPasswd;
if ( GetPasswd_Impl( pSet, aPasswd ) )
aStorage->SetKey( S2BS( aPasswd ) );
}
pImp->bIsStorage = pImp->xStorage.is();
return pImp->xStorage;
}
//------------------------------------------------------------------
void SfxMedium::CloseStorage()
{
aStorage.Clear();
if ( pImp->xStorage.is() )
{
uno::Reference < lang::XComponent > xComp( pImp->xStorage, uno::UNO_QUERY );
if ( pImp->bDisposeStorage )
xComp->dispose();
pImp->xStorage = 0;
}
bTriedStorage = sal_False;
pImp->bIsStorage = sal_False;
}
void SfxMedium::DontDisposeStorage_Impl()
{
pImp->bDisposeStorage = FALSE;
}
//------------------------------------------------------------------
void SfxMedium::SetOpenMode( StreamMode nStorOpen,
sal_Bool bDirectP,
@@ -1223,6 +1229,90 @@ void SfxMedium::SetOpenMode( StreamMode nStorOpen,
bSetFilter = sal_False;
}
//------------------------------------------------------------------
sal_Bool SfxMedium::UseBackupToRestore_Impl( ::ucb::Content& aOriginalContent,
const Reference< ::com::sun::star::ucb::XCommandEnvironment >& xComEnv )
{
try
{
::ucb::Content aTransactCont( pImp->m_aBackupURL, xComEnv );
Reference< XInputStream > aOrigInput = aTransactCont.openStream();
aOriginalContent.writeStream( aOrigInput, sal_True );
return sal_True;
}
catch( Exception& )
{
// in case of failure here the backup file should not be removed
// TODO/LATER: a message should be used to let user know about the backup
pImp->m_bRemoveBackup = sal_False;
// TODO/LATER: needs a specific error code
eError = ERRCODE_IO_GENERAL;
}
return sal_False;
}
//------------------------------------------------------------------
sal_Bool SfxMedium::StorageCommit_Impl()
{
sal_Bool bResult = sal_False;
Reference< ::com::sun::star::ucb::XCommandEnvironment > xDummyEnv;
::ucb::Content aOriginalContent;
if ( pImp->xStorage.is() )
{
StorageBackup_Impl();
if ( !GetError() )
{
uno::Reference < embed::XTransactedObject > xTrans( pImp->xStorage, uno::UNO_QUERY );
if ( xTrans.is() )
{
try
{
xTrans->commit();
bResult = sal_True;
}
catch ( embed::UseBackupException& aBackupExc )
{
if ( !pImp->pTempFile )
{
OSL_ENSURE( pImp->m_aBackupURL.getLength(), "No backup on storage commit!\n" );
if ( pImp->m_aBackupURL.getLength()
&& ::ucb::Content::create( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ),
xDummyEnv,
aOriginalContent ) )
{
// use backup to restore the file
// the storage has already disconnected from original location
CloseStreams_Impl();
if ( !UseBackupToRestore_Impl( aOriginalContent, xDummyEnv ) )
{
// connect the medium to the temporary file of the storage
pImp->aContent = ::ucb::Content();
aName = aBackupExc.TemporaryFileURL;
OSL_ENSURE( aName.Len(), "The exception _must_ contain the temporary URL!\n" );
}
}
if ( !GetError() )
SetError( ERRCODE_IO_GENERAL );
}
}
catch ( uno::Exception& )
{
//TODO/LATER: improve error handling
SetError( ERRCODE_IO_GENERAL );
}
}
}
}
return bResult;
}
//------------------------------------------------------------------
sal_Bool SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource,
const INetURLObject& aDest,
const Reference< ::com::sun::star::ucb::XCommandEnvironment >& xComEnv )
@@ -1259,6 +1349,8 @@ sal_Bool SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource,
{
Reference< XInputStream > aTempInput = aTempCont.openStream();
bTransactStarted = sal_True;
aOriginalContent.setPropertyValue( ::rtl::OUString::createFromAscii( "Size" ),
uno::makeAny( (sal_Int64)0 ) );
aOriginalContent.writeStream( aTempInput, bOverWrite );
bResult = sal_True;
}
@@ -1294,7 +1386,7 @@ sal_Bool SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource,
else
eError = ERRCODE_IO_GENERAL;
}
catch ( ::com::sun::star::uno::Exception& e )
catch ( ::com::sun::star::uno::Exception& )
{
eError = ERRCODE_IO_GENERAL;
}
@@ -1311,21 +1403,7 @@ sal_Bool SfxMedium::TransactedTransferForFS_Impl( const INetURLObject& aSource,
}
else if ( bTransactStarted )
{
try
{
::ucb::Content aTransactCont;
if( ::ucb::Content::create( pImp->m_aBackupURL, xDummyEnv, aTransactCont ) )
{
Reference< XInputStream > aOrigInput = aTransactCont.openStream();
aOriginalContent.writeStream( aOrigInput, sal_True );
}
}
catch( Exception& )
{
// in case of failure here the backup file should not be removed
pImp->m_bRemoveBackup = sal_False;
eError = ERRCODE_IO_GENERAL;
}
UseBackupToRestore_Impl( aOriginalContent, xDummyEnv );
}
}
else
@@ -1394,7 +1472,8 @@ void SfxMedium::Transfer_Impl()
}
// free the reference
pSet->ClearItem( SID_OUTPUTSTREAM );
if ( pSet )
pSet->ClearItem( SID_OUTPUTSTREAM );
return;
}
@@ -1410,27 +1489,39 @@ void SfxMedium::Transfer_Impl()
if ( pSegmentSize )
{
// this file must be stored into a disk spanned package
SotStorageRef xStor = new SotStorage( TRUE, GetName(), STREAM_STD_READWRITE | STREAM_TRUNC, STORAGE_TRANSACTED );
if ( xStor->GetError() == ERRCODE_NONE )
try
{
uno::Reference < embed::XStorage > xStor = comphelper::OStorageHelper::GetStorageFromURL( GetName(),
embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
// set segment size property; package will automatically be divided in pieces fitting
// into this size
::com::sun::star::uno::Any aAny;
aAny <<= pSegmentSize->GetValue();
xStor->SetProperty( String::CreateFromAscii("SegmentSize"), aAny );
uno::Reference < beans::XPropertySet > xSet( pImp->xStorage, uno::UNO_QUERY );
xSet->setPropertyValue( String::CreateFromAscii("SegmentSize"), aAny );
// copy the temporary storage into the disk spanned package
GetStorage()->CopyTo( xStor );
xStor->Commit();
}
GetStorage()->copyToStorage( xStor );
uno::Reference < embed::XTransactedObject > xTrans( pImp->xStorage, uno::UNO_QUERY );
if ( xTrans.is() )
xTrans->commit();
if ( !GetError() )
SetError( xStor->GetError() );
}
catch ( uno::Exception& )
{
//TODO/MBA: error handling
//if ( !GetError() )
// SetError( xStor->GetError() );
}
return;
}
if ( pFilter && SOFFICE_FILEFORMAT_60 <= pFilter->GetVersion() )
{
//TODO/LATER: how?!
/*
SFX_ITEMSET_ARG( GetItemSet(), pItem, SfxBoolItem, SID_UNPACK, sal_False);
if ( pItem && pItem->GetValue() )
{
@@ -1451,7 +1542,7 @@ void SfxMedium::Transfer_Impl()
SvStorageRef xStor = new SvStorage( TRUE, GetName(), STREAM_STD_READWRITE, STORAGE_CREATE_UNPACKED );
// copy package into unpacked storage
if ( xStor->GetError() == ERRCODE_NONE && GetStorage()->CopyTo( xStor ) )
if ( xStor->GetError() == ERRCODE_NONE && GetStorage()->copyToStorage( xStor ) )
{
// commit changes, writing will happen now
xStor->Commit();
@@ -1465,7 +1556,7 @@ void SfxMedium::Transfer_Impl()
else if ( !GetError() )
SetError( xStor->GetError() );
return;
}
}*/
}
INetURLObject aDest( GetURLObject() );
@@ -1566,7 +1657,7 @@ void SfxMedium::Transfer_Impl()
else
eError = ERRCODE_IO_GENERAL;
}
catch ( ::com::sun::star::uno::Exception& e )
catch ( ::com::sun::star::uno::Exception& )
{
eError = ERRCODE_IO_GENERAL;
}
@@ -1727,17 +1818,26 @@ void SfxMedium::GetMedium_Impl()
if ( !pInStream )
{
pImp->bDownloadDone = sal_False;
pImp->bStreamReady = sal_False;
Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = GetInteractionHandler();
::utl::UcbLockBytesHandler* pHandler = pImp->aHandler;
INetProtocol eProt = GetURLObject().GetProtocol();
if ( eProt != INET_PROT_HTTP && eProt != INET_PROT_FTP || aName.Len() )
pHandler = NULL;
BOOL bSynchron = pImp->bForceSynchron || ! pImp->aDoneLink.IsSet();
SFX_ITEMSET_ARG( pSet, pStreamItem, SfxUnoAnyItem, SID_INPUTSTREAM, sal_False);
if ( pStreamItem )
//TODO/MBA: need support for SID_STREAM
SFX_ITEMSET_ARG( pSet, pWriteStreamItem, SfxUnoAnyItem, SID_STREAM, sal_False);
SFX_ITEMSET_ARG( pSet, pInStreamItem, SfxUnoAnyItem, SID_INPUTSTREAM, sal_False);
if ( pWriteStreamItem )
{
pWriteStreamItem->GetValue() >>= pImp->xStream;
if ( pInStreamItem )
pInStreamItem->GetValue() >>= pImp->xInputStream;
if ( !pImp->xInputStream.is() && pImp->xStream.is() )
pImp->xInputStream = pImp->xStream->getInputStream();
}
else if ( pInStreamItem )
{
// TODO/LATER: if the document still must be opened in readwrite mode additional implementation is required
if ( GetContent().is() && !IsReadOnly() )
{
try
@@ -1755,111 +1855,47 @@ void SfxMedium::GetMedium_Impl()
}
}
Reference < ::com::sun::star::io::XInputStream > xStream;
if ( ( pStreamItem->GetValue() >>= xStream ) && xStream.is() )
pImp->xLockBytes = utl::UcbLockBytes::CreateInputLockBytes( xStream );
Done_Impl( pImp->xLockBytes.Is() ? pImp->xLockBytes->GetError() : ERRCODE_IO_NOTSUPPORTED );
pInStreamItem->GetValue() >>= pImp->xInputStream;
}
else
{
// TODO: DBG_ERROR("SfxMedium::GetMediumImpl()\nCreate Stream? This code exists as fallback only. Please clarify, why its used.");
SFX_ITEMSET_ARG( GetItemSet(), pItem, SfxBoolItem, SID_DOC_READONLY, sal_False);
BOOL bAllowReadOnlyMode = pItem ? pItem->GetValue() : TRUE;
BOOL bIsWritable = ( nStorOpenMode & STREAM_WRITE );
SFX_ITEMSET_ARG( GetItemSet(), pPostDataItem, SfxUnoAnyItem, SID_POSTDATA, sal_False);
SFX_ITEMSET_ARG( GetItemSet(), pContentTypeItem, SfxStringItem, SID_CONTENT_TYPE, sal_False);
SFX_ITEMSET_ARG( GetItemSet(), pRefererItem, SfxStringItem, SID_REFERER, sal_False);
::rtl::OUString aReferer;
if ( pRefererItem )
aReferer = pRefererItem->GetValue();
if ( pPostDataItem )
uno::Sequence < beans::PropertyValue > xProps;
String aFileName;
if ( aName.Len() )
{
DBG_ASSERT( bAllowReadOnlyMode, "Strange open mode!" );
bIsWritable = FALSE;
GetItemSet()->Put( SfxBoolItem(SID_DOC_READONLY, sal_True));
SetOpenMode(SFX_STREAM_READONLY, sal_False);
::rtl::OUString aMimeType;
if ( pContentTypeItem )
aMimeType = pContentTypeItem->GetValue();
else
aMimeType = ::rtl::OUString::createFromAscii( "application/x-www-form-urlencoded" );
Reference < XInputStream > xPostData;
if ( pPostDataItem )
{
Any aAny = pPostDataItem->GetValue();
aAny >>= xPostData;
}
pImp->xLockBytes = ::utl::UcbLockBytes::CreateLockBytes(
GetContent(), aReferer, aMimeType, xPostData, xInteractionHandler, pHandler );
if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aFileName ) )
DBG_ERROR("Physical name not convertable!");
}
else
{
// no callbacks for opening read/write because we might try readonly later
pImp->bDontCallDoneLinkOnSharingError = ( bIsWritable && bAllowReadOnlyMode );
if ( pImp->bDontCallDoneLinkOnSharingError )
{
::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > aTempHandler =
new SfxMediumHandler_Impl( xInteractionHandler );
pImp->xLockBytes = ::utl::UcbLockBytes::CreateLockBytes(
GetContent(), Sequence < PropertyValue >(), nStorOpenMode, aTempHandler );
}
else
pImp->xLockBytes = ::utl::UcbLockBytes::CreateLockBytes(
GetContent(), Sequence < PropertyValue >(), nStorOpenMode, xInteractionHandler, bIsWritable ? NULL : pHandler );
}
aFileName = GetName();
if ( !pImp->xLockBytes.Is() )
{
pImp->bDontCallDoneLinkOnSharingError = sal_False;
Done_Impl( ERRCODE_IO_NOTEXISTS );
}
else if ( pImp->xLockBytes->GetError() == ERRCODE_IO_ACCESSDENIED && bIsWritable && bAllowReadOnlyMode ||
pImp->xLockBytes->GetError() == ERRCODE_IO_NOTSUPPORTED && bIsWritable )
{
if ( pImp->xLockBytes->GetError() == ERRCODE_IO_ACCESSDENIED )
{
GetItemSet()->Put( SfxBoolItem(SID_DOC_READONLY, sal_True));
SetOpenMode(SFX_STREAM_READONLY, sal_False);
}
GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, aFileName ) );
TransformItems( SID_OPENDOC, *GetItemSet(), xProps );
comphelper::MediaDescriptor aMedium( xProps );
aMedium.addInputStream();
ResetError();
pImp->bDownloadDone = sal_False;
pImp->bDontCallDoneLinkOnSharingError = sal_False;
pImp->xLockBytes = ::utl::UcbLockBytes::CreateLockBytes(
GetContent(), Sequence < PropertyValue >(), SFX_STREAM_READONLY, xInteractionHandler, pHandler );
//TODO/MBA: what happens if property is not there?!
GetContent();
aMedium[comphelper::MediaDescriptor::PROP_STREAM()] >>= pImp->xStream;
aMedium[comphelper::MediaDescriptor::PROP_INPUTSTREAM()] >>= pImp->xInputStream;
if ( !pImp->xInputStream.is() && pImp->xStream.is() )
pImp->xInputStream = pImp->xStream->getInputStream();
if ( !pHandler && !pImp->bDownloadDone )
Done_Impl( pImp->xLockBytes->GetError() );
}
else if ( !pHandler && !pImp->bDownloadDone )
// opening readwrite is always done synchronously
Done_Impl( pImp->xLockBytes->GetError() );
//TODO/MBA: need support for SID_STREAM
if ( pImp->xStream.is() )
GetItemSet()->Put( SfxUsrAnyItem( SID_STREAM, makeAny( pImp->xStream ) ) );
GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM, makeAny( pImp->xInputStream ) ) );
}
if ( pImp->xLockBytes.Is() && !GetError() )
{
if ( bSynchron )
pImp->xLockBytes->SetSynchronMode( sal_True );
if ( !pImp->bDownloadDone )
pImp->pCancellable = new UcbLockBytesCancellable_Impl( pImp->xLockBytes, pImp->GetCancelManager(),
GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
pInStream = new SvStream( pImp->xLockBytes );
pInStream->SetBufferSize( 4096 );
pImp->bStreamReady = sal_True;
}
//TODO/MBA: ErrorHandling - how to transport error from MediaDescriptor
if ( !GetError() && !pImp->xStream.is() && !pImp->xInputStream.is() )
SetError( ERRCODE_IO_NOTSUPPORTED );
pImp->bDownloadDone = sal_True;
pImp->aDoneLink.ClearPendingCall();
pImp->aDoneLink.Call( (void*) GetError() );
}
// Download completion happened while pInStream was constructed
if ( pImp->bDownloadDone )
Done_Impl( GetError() );
}
//------------------------------------------------------------------
@@ -1990,6 +2026,7 @@ void SfxMedium::Init_Impl()
{
Reference< XOutputStream > rOutStream;
pImp->pVersions = NULL;
pImp->bDisposeStorage = TRUE;
SFX_ITEMSET_ARG( pSet, pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False);
if( aLogicName.Len() )
@@ -2130,11 +2167,12 @@ void SfxMedium::SetOrigFilter_Impl( const SfxFilter* pFilter )
void SfxMedium::Close()
{
if ( aStorage.Is() )
if ( pImp->xStorage.is() )
{
// don't close the streams if they belong to the
// storage
//TODO/MBA: how to?! Do we need the flag?!
/*
const SvStream *pStream = aStorage->GetSvStream();
if ( pStream && pStream == pInStream )
{
@@ -2149,16 +2187,19 @@ void SfxMedium::Close()
{
pOutStream = NULL;
aStorage->SetDeleteStream( TRUE );
}
} */
CloseStorage();
}
if ( pInStream )
CloseInStream_Impl();
CloseStreams_Impl();
}
if ( pOutStream )
CloseOutStream_Impl();
//------------------------------------------------------------------
void SfxMedium::CloseStreams_Impl()
{
CloseInStream_Impl();
CloseOutStream_Impl();
if ( pSet )
pSet->ClearItem( SID_CONTENT );
@@ -2251,6 +2292,26 @@ void SfxMedium::SetPhysicalName_Impl( const String& rNameP )
}
//----------------------------------------------------------------
void SfxMedium::MoveStorageTo_Impl( SfxMedium* pMedium )
{
if ( pMedium && pMedium != this && pImp->xStorage.is() )
{
if( pMedium->pImp->pTempFile )
{
pMedium->pImp->pTempFile->EnableKillingFile( sal_True );
delete pMedium->pImp->pTempFile;
pMedium->pImp->pTempFile = NULL;
}
pMedium->Close();
pMedium->aName = aName;
pMedium->pImp->xStorage = pImp->xStorage;
DontDisposeStorage_Impl();
}
}
//----------------------------------------------------------------
void SfxMedium::MoveTempTo_Impl( SfxMedium* pMedium )
{
if ( pMedium && pMedium != this && pImp->pTempFile )
@@ -2296,15 +2357,7 @@ void SfxMedium::ReOpen()
{
BOOL bUseInteractionHandler = pImp->bUseInteractionHandler;
pImp->bUseInteractionHandler = FALSE;
DBG_ASSERT( pFilter, "Kein Filter, aber ReOpen!" );
if( pFilter )
{
if( pFilter->UsesStorage() )
GetStorage();
else
GetInStream();
}
GetMedium_Impl();
pImp->bUseInteractionHandler = bUseInteractionHandler;
}
//------------------------------------------------------------------
@@ -2325,17 +2378,18 @@ SfxMedium::SfxMedium
}
//------------------------------------------------------------------
SfxMedium::SfxMedium( SvStorage *pStorage, sal_Bool bRootP )
SfxMedium::SfxMedium( const uno::Reference < embed::XStorage >& rStor, sal_Bool bRootP )
: IMPL_CTOR( bRootP, 0 ), // bRoot, pURLObj
aStorage(pStorage),
pSet(0),
pImp( new SfxMedium_Impl( this ))
{
String aType = SfxFilter::GetTypeFromStorage( *pStorage );
String aType = SfxFilter::GetTypeFromStorage( rStor );
pFilter = SFX_APP()->GetFilterMatcher().GetFilter4EA( aType );
DBG_ASSERT( pFilter, "No Filter for storage found!" );
Init_Impl();
pImp->xStorage = rStor;
pImp->bDisposeStorage = FALSE;
}
//------------------------------------------------------------------
@@ -2348,9 +2402,6 @@ SfxMedium::~SfxMedium()
=> further the help will be empty then ... #100490#
*/
//CancelTransfers();
::vos::OClearableGuard aGuard( pImp->aHandler->GetMutex() );
pImp->aHandler->ReleaseMedium();
aGuard.clear();
Close();
@@ -2477,33 +2528,6 @@ void SfxMedium::ForceSynchronStream_Impl( sal_Bool bForce )
}
pImp->bForceSynchron = bForce;
}
//----------------------------------------------------------------
/* Kann der URL ein MIME Type zugeordnent werden? */
sal_Bool SfxMedium::SupportsMIME_Impl() const
{
INetProtocol eProt = GetURLObject().GetProtocol();
if( eProt == INET_PROT_HTTPS || eProt == INET_PROT_HTTP )
return sal_True;
if( eProt == INET_PROT_NOT_VALID )
return sal_False;
if( eProt == INET_PROT_FTP )
{
try
{
Any aAny = pImp->aContent.getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsFolder")) );
sal_Bool bIsFolder = FALSE;
if ( ( aAny >>= bIsFolder ) && bIsFolder )
return SvBinding::ShouldUseFtpProxy( GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
}
catch ( ::com::sun::star::uno::Exception& )
{
}
}
return sal_False;
}
//----------------------------------------------------------------
SfxFrame* SfxMedium::GetLoadTargetFrame() const
@@ -2518,9 +2542,9 @@ void SfxMedium::SetLoadTargetFrame(SfxFrame* pFrame )
}
//----------------------------------------------------------------
void SfxMedium::SetStorage_Impl( SvStorage* pStor )
void SfxMedium::SetStorage_Impl( const uno::Reference < embed::XStorage >& rStor )
{
aStorage = pStor;
pImp->xStorage = rStor;
}
//----------------------------------------------------------------
@@ -2597,59 +2621,64 @@ void SfxMedium::SetDontCreateCancellable( )
::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SfxMedium::GetInputStream()
{
if ( !pImp->xInputStream.is() )
{
// if pInStream is already opened then we have problem
// probably GetInStream should allways open pInStream based on xInputStream
GetMedium_Impl();
}
return pImp->xInputStream;
}
const SfxVersionTableDtor* SfxMedium::GetVersionList()
{
if ( !pImp->pVersions && GetStorage() )
if ( !pImp->pVersions && GetStorage().is() )
{
if ( pImp->bIsDiskSpannedJAR )
return NULL;
SvStorageStreamRef aStream =
GetStorage()->OpenStream( DEFINE_CONST_UNICODE( "VersionList" ), SFX_STREAM_READONLY | STREAM_NOCREATE );
if ( aStream.Is() && aStream->GetError() == SVSTREAM_OK )
try
{
pImp->pVersions = new SfxVersionTableDtor;
pImp->pVersions->Read( *aStream );
}
else
{
SfxVersionTableDtor *pList = new SfxVersionTableDtor;
if ( SfxXMLVersList_Impl::ReadInfo( GetStorage(), pList ) )
pImp->pVersions = pList;
uno::Reference < io::XStream > xStream = GetStorage()->openStreamElement( DEFINE_CONST_UNICODE( "VersionList" ),
embed::ElementModes::READ );
if ( xStream.is() )
{
SvStream* pStr = utl::UcbStreamHelper::CreateStream( xStream );
pImp->pVersions = new SfxVersionTableDtor;
pImp->pVersions->Read( *pStr );
delete pStr;
}
else
delete pList;
{
SfxVersionTableDtor *pList = new SfxVersionTableDtor;
if ( SfxXMLVersList_Impl::ReadInfo( GetStorage(), pList ) )
pImp->pVersions = pList;
else
delete pList;
}
}
catch ( uno::Exception& )
{
//TODO/MBA: error handling
}
}
return pImp->pVersions;
}
SfxVersionTableDtor* SfxMedium::GetVersionList( SvStorage* pStor )
SfxVersionTableDtor* SfxMedium::GetVersionList( const uno::Reference < embed::XStorage >& xStor )
{
SfxVersionTableDtor* pVersions = NULL;
if( pStor )
if( xStor.is() )
{
SvStorageStreamRef aStream =
pStor->OpenStream( DEFINE_CONST_UNICODE( "VersionList" ), SFX_STREAM_READONLY | STREAM_NOCREATE );
if ( aStream.Is() && aStream->GetError() == SVSTREAM_OK )
uno::Reference < io::XStream > xStream = xStor->openStreamElement( DEFINE_CONST_UNICODE( "VersionList" ),
embed::ElementModes::READ );
if ( xStream.is() )
{
SvStream* pStr = utl::UcbStreamHelper::CreateStream( xStream );
pVersions = new SfxVersionTableDtor;
pVersions->Read( *aStream );
pVersions->Read( *pStr );
delete pStr;
}
else
{
SfxVersionTableDtor *pList = new SfxVersionTableDtor;
if ( SfxXMLVersList_Impl::ReadInfo( pStor, pList ) )
if ( SfxXMLVersList_Impl::ReadInfo( xStor, pList ) )
pVersions = pList;
else
delete pList;
@@ -2662,7 +2691,7 @@ SfxVersionTableDtor* SfxMedium::GetVersionList( SvStorage* pStor )
sal_uInt16 SfxMedium::AddVersion_Impl( SfxVersionInfo& rInfo )
{
if ( GetStorage() )
if ( GetStorage().is() )
{
if ( !pImp->pVersions )
pImp->pVersions = new SfxVersionTableDtor;
@@ -2732,23 +2761,25 @@ sal_Bool SfxMedium::TransferVersionList_Impl( SfxMedium& rMedium )
sal_Bool SfxMedium::SaveVersionList_Impl( sal_Bool bUseXML )
{
if ( GetStorage() )
if ( GetStorage().is() )
{
if ( !pImp->pVersions )
return sal_True;
if ( bUseXML )
{
SfxXMLVersList_Impl::WriteInfo( aStorage, pImp->pVersions );
SfxXMLVersList_Impl::WriteInfo( pImp->xStorage, pImp->pVersions );
return sal_True;
}
else
{
SvStorageStreamRef aStream =
GetStorage()->OpenStream( DEFINE_CONST_UNICODE( "VersionList" ), SFX_STREAM_READWRITE );
if ( aStream.Is() && aStream->GetError() == SVSTREAM_OK )
uno::Reference < io::XStream > xStream = GetStorage()->openStreamElement( DEFINE_CONST_UNICODE( "VersionList" ),
embed::ElementModes::READWRITE );
if ( xStream.is() )
{
pImp->pVersions->Write( *aStream );
SvStream* pStr = utl::UcbStreamHelper::CreateStream( xStream );
pImp->pVersions->Write( *pStr );
delete pStr;
return sal_True;
}
}
@@ -2790,8 +2821,8 @@ void SfxMedium::TryToSwitchToRepairedTemp()
SFX_ITEMSET_ARG( GetItemSet(), pRepairItem, SfxBoolItem, SID_REPAIRPACKAGE, FALSE );
if ( pRepairItem && pRepairItem->GetValue() )
{
DBG_ASSERT( aStorage, "Possible performance problem" );
if ( GetStorage() )
DBG_ASSERT( pImp->xStorage.is(), "Possible performance problem" );
if ( GetStorage().is() )
{
::utl::TempFile* pTmpFile = new ::utl::TempFile();
pTmpFile->EnableKillingFile( sal_True );
@@ -2799,13 +2830,14 @@ void SfxMedium::TryToSwitchToRepairedTemp()
if( aNewName.getLength() )
{
SvStorageRef aNewStorage = new SvStorage( sal_True, aNewName, STREAM_WRITE | STREAM_TRUNC, STORAGE_TRANSACTED );
if ( aNewStorage->GetError() == SVSTREAM_OK )
try
{
aStorage->CopyTo( &aNewStorage );
aNewStorage->Commit();
uno::Reference < embed::XStorage > xNewStorage = comphelper::OStorageHelper::GetStorageFromURL( aNewName,
embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
//SvStorageRef aNewStorage = new SvStorage( sal_True, aNewName, STREAM_WRITE | STREAM_TRUNC, STORAGE_TRANSACTED );
if ( aNewStorage->GetError() == SVSTREAM_OK )
pImp->xStorage->copyToStorage( xNewStorage );
//if ( aNewStorage->GetError() == SVSTREAM_OK )
{
CloseInStream();
CloseStorage();
@@ -2816,8 +2848,11 @@ void SfxMedium::TryToSwitchToRepairedTemp()
aName = aNewName;
}
}
SetError( aNewStorage->GetError() );
catch ( uno::Exception& )
{
//TODO/MBA: error handling
//SetError( aNewStorage->GetError() );
}
}
else
SetError( ERRCODE_IO_CANTWRITE );
@@ -2834,8 +2869,34 @@ void SfxMedium::CreateTempFile()
DELETEZ( pImp->pTempFile );
StreamMode nOpenMode = nStorOpenMode;
GetInStream();
BOOL bCopy = ( nStorOpenMode == nOpenMode && ! ( nOpenMode & STREAM_TRUNC ) );
if ( bCopy && !pInStream )
{
if ( GetContent().is() )
{
try
{
// make sure that the desired file exists before trying to open
SvMemoryStream aStream(0,0);
::utl::OInputStreamWrapper* pInput = new ::utl::OInputStreamWrapper( aStream );
Reference< XInputStream > xInput( pInput );
InsertCommandArgument aInsertArg;
aInsertArg.Data = xInput;
aInsertArg.ReplaceExisting = sal_False;
Any aCmdArg;
aCmdArg <<= aInsertArg;
pImp->aContent.executeCommand( ::rtl::OUString::createFromAscii( "insert" ), aCmdArg );
}
catch ( Exception& )
{
// it is NOT an error when the stream already exists!
GetInStream();
}
}
}
nStorOpenMode = nOpenMode;
ResetError();
@@ -2848,10 +2909,10 @@ void SfxMedium::CreateTempFile()
return;
}
if ( bCopy )
if ( bCopy && pInStream )
{
GetOutStream();
if ( pInStream && pOutStream )
if ( pOutStream )
{
char *pBuf = new char [8192];
sal_uInt32 nErr = ERRCODE_NONE;
@@ -3064,3 +3125,68 @@ SvStringsDtor* SfxVersionTableDtor::GetVersions() const
return pList;
}
SV_DECL_PTRARR_DEL(SvKeyValueList_Impl, SvKeyValue*, 0, 4);
SV_IMPL_PTRARR(SvKeyValueList_Impl, SvKeyValue*);
/*
* SvKeyValueIterator.
*/
SvKeyValueIterator::SvKeyValueIterator (void)
: m_pList (new SvKeyValueList_Impl),
m_nPos (0)
{
}
/*
* ~SvKeyValueIterator.
*/
SvKeyValueIterator::~SvKeyValueIterator (void)
{
delete m_pList;
}
/*
* GetFirst.
*/
BOOL SvKeyValueIterator::GetFirst (SvKeyValue &rKeyVal)
{
m_nPos = m_pList->Count();
return GetNext (rKeyVal);
}
/*
* GetNext.
*/
BOOL SvKeyValueIterator::GetNext (SvKeyValue &rKeyVal)
{
if (m_nPos > 0)
{
rKeyVal = *m_pList->GetObject(--m_nPos);
return TRUE;
}
else
{
// Nothing to do.
return FALSE;
}
}
/*
* Append.
*/
void SvKeyValueIterator::Append (const SvKeyValue &rKeyVal)
{
SvKeyValue *pKeyVal = new SvKeyValue (rKeyVal);
m_pList->C40_INSERT(SvKeyValue, pKeyVal, m_pList->Count());
}
BOOL SfxMedium::HasStorage_Impl() const
{
return pImp->xStorage.is();
}
BOOL SfxMedium::IsOpen() const
{
return pInStream || pOutStream || pImp->xStorage.is();
}