/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sot.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef _TOOLS_FSYS_HXX #include #endif #include #include #include #include #include #include #include "unostorageholder.hxx" using namespace ::com::sun::star; /************** class SotStorageStream ***********************************/ class SotStorageStreamFactory : public SotFactory { public: TYPEINFO(); SotStorageStreamFactory( const SvGlobalName & rName, const String & rClassName, CreateInstanceType pCreateFuncP ) : SotFactory( rName, rClassName, pCreateFuncP ) {} }; TYPEINIT1(SotStorageStreamFactory,SotFactory); SO2_IMPL_BASIC_CLASS1_DLL(SotStorageStream,SotStorageStreamFactory,SotObject, SvGlobalName( 0xd7deb420, 0xf902, 0x11d0, 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) ) SO2_IMPL_INVARIANT(SotStorageStream) void SotStorageStream::TestMemberObjRef( sal_Bool /*bFree*/ ) { } #ifdef TEST_INVARIANT void SotStorageStream::TestMemberInvariant( sal_Bool /*bPrint*/ ) { } #endif /************************************************************************ |* SotStorageStream::SotStorageStream() |* |* Beschreibung *************************************************************************/ SvLockBytesRef MakeLockBytes_Impl( const String & rName, StreamMode nMode ) { SvLockBytesRef xLB; if( rName.Len() ) { SvStream * pFileStm = new SvFileStream( rName, nMode ); xLB = new SvLockBytes( pFileStm, sal_True ); } else { SvStream * pCacheStm = new SvCacheStream(); xLB = new SvLockBytes( pCacheStm, sal_True ); } return xLB; } SotStorageStream::SotStorageStream( const String & rName, StreamMode nMode, StorageMode #ifdef DBG_UTIL nStorageMode #endif ) : SvStream( MakeLockBytes_Impl( rName, nMode ) ) , pOwnStm( NULL ) { if( nMode & STREAM_WRITE ) bIsWritable = sal_True; else bIsWritable = sal_False; DBG_ASSERT( !nStorageMode,"StorageModes ignored" ); } SotStorageStream::SotStorageStream( BaseStorageStream * pStm ) { if( pStm ) { if( STREAM_WRITE & pStm->GetMode() ) bIsWritable = sal_True; else bIsWritable = sal_False; pOwnStm = pStm; SetError( pStm->GetError() ); pStm->ResetError(); } else { pOwnStm = NULL; bIsWritable = sal_True; SetError( SVSTREAM_INVALID_PARAMETER ); } } SotStorageStream::SotStorageStream() : pOwnStm( NULL ) { // ??? wenn Init virtuell ist, entsprechen setzen bIsWritable = sal_True; } /************************************************************************ |* SotStorageStream::~SotStorageStream() |* |* Beschreibung *************************************************************************/ SotStorageStream::~SotStorageStream() { Flush(); //SetBufferSize(0); delete pOwnStm; } /************************************************************************* |* SotStorageStream::SyncSvStream() |* |* Beschreibung: Der SvStream wird auf den Zustand des Standard-Streams |* gesetzt. Der Puffer des SvStreams wird weggeworfen. *************************************************************************/ void SotStorageStream::SyncSvStream() { sal_uLong nPos = 0; if( pOwnStm ) { pOwnStm->Flush(); nPos = pOwnStm->Tell(); SetError( pOwnStm->GetError() ); SvStream::SyncSvStream( nPos ); } } /************************************************************************* |* SotStorageStream::ResetError() |* |* Beschreibung *************************************************************************/ void SotStorageStream::ResetError() { SvStream::ResetError(); if( pOwnStm ) pOwnStm->ResetError(); } /************************************************************************* |* SotStorageStream::GetData() |* |* Beschreibung *************************************************************************/ sal_uLong SotStorageStream::GetData( void* pData, sal_uLong nSize ) { sal_uLong nRet = 0; if( pOwnStm ) { nRet = pOwnStm->Read( pData, nSize ); SetError( pOwnStm->GetError() ); } else nRet = SvStream::GetData( (sal_Char *)pData, nSize ); return nRet; } /************************************************************************* |* SotStorageStream::PutData() |* |* Beschreibung *************************************************************************/ sal_uLong SotStorageStream::PutData( const void* pData, sal_uLong nSize ) { sal_uLong nRet = 0; if( pOwnStm ) { nRet = pOwnStm->Write( pData, nSize ); SetError( pOwnStm->GetError() ); } else nRet = SvStream::PutData( (sal_Char *)pData, nSize ); return nRet; } /************************************************************************* |* SotStorageStream::SeekPos() |* |* Beschreibung *************************************************************************/ sal_uLong SotStorageStream::SeekPos( sal_uLong nPos ) { sal_uLong nRet = 0; if( pOwnStm ) { nRet = pOwnStm->Seek( nPos ); SetError( pOwnStm->GetError() ); } else nRet = SvStream::SeekPos( nPos ); return nRet; } /************************************************************************* |* SotStorageStream::Flush() |* |* Beschreibung *************************************************************************/ void SotStorageStream::FlushData() { if( pOwnStm ) { pOwnStm->Flush(); SetError( pOwnStm->GetError() ); } else SvStream::FlushData(); } /************************************************************************* |* SotStorageStream::SetSize() |* |* Beschreibung *************************************************************************/ void SotStorageStream::SetSize( sal_uLong nNewSize ) { sal_uLong nPos = Tell(); if( pOwnStm ) { pOwnStm->SetSize( nNewSize ); SetError( pOwnStm->GetError() ); } else SvStream::SetSize( nNewSize ); if( nNewSize < nPos ) // ans Ende setzen Seek( nNewSize ); //return GetError() == SVSTREAM_OK; } /************************************************************************* |* |* SotStorageStream::GetSize() |* |* Beschreibung |* *************************************************************************/ sal_uInt32 SotStorageStream::GetSize() const { sal_uLong nPos = Tell(); ((SotStorageStream *)this)->Seek( STREAM_SEEK_TO_END ); sal_uLong nSize = Tell(); ((SotStorageStream *)this)->Seek( nPos ); return nSize; } /************************************************************************* |* SotStorageStream::CopyTo() |* |* Beschreibung *************************************************************************/ sal_Bool SotStorageStream::CopyTo( SotStorageStream * pDestStm ) { Flush(); // alle Daten schreiben pDestStm->ClearBuffer(); if( !pOwnStm || !pDestStm->pOwnStm ) { // Wenn Ole2 oder nicht nur eigene StorageStreams sal_uLong nPos = Tell(); // Position merken Seek( 0L ); pDestStm->SetSize( 0 ); // Ziel-Stream leeren void * pMem = new sal_uInt8[ 8192 ]; sal_uLong nRead; while( 0 != (nRead = Read( pMem, 8192 )) ) { if( nRead != pDestStm->Write( pMem, nRead ) ) { SetError( SVSTREAM_GENERALERROR ); break; } } delete [] static_cast(pMem); // Position setzen pDestStm->Seek( nPos ); Seek( nPos ); } else { /* // Kopieren nErr = pObjI->CopyTo( pDestStm->pObjI, uSize, NULL, &uWrite ); if( SUCCEEDED( nErr ) ) { // Ziel-Streamzeiger steht hinter den Daten // SvSeek abgleichen pDestStm->Seek( uWrite.LowPart ); } else if( GetScode( nErr ) == E_NOTIMPL ) { // Eines Tages werden alle MS... ?!# */ pOwnStm->CopyTo( pDestStm->pOwnStm ); SetError( pOwnStm->GetError() ); } return GetError() == SVSTREAM_OK; } /************************************************************************* |* SotStorageStream::Commit() |* SotStorageStream::Revert() |* |* Beschreibung *************************************************************************/ sal_Bool SotStorageStream::Commit() { if( pOwnStm ) { pOwnStm->Flush(); if( pOwnStm->GetError() == SVSTREAM_OK ) pOwnStm->Commit(); SetError( pOwnStm->GetError() ); } return GetError() == SVSTREAM_OK; } sal_Bool SotStorageStream::Revert() { if( !pOwnStm ) { pOwnStm->Revert(); SetError( pOwnStm->GetError() ); } return GetError() == SVSTREAM_OK; } sal_Bool SotStorageStream::SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue ) { UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pOwnStm ); if ( pStg ) { return pStg->SetProperty( rName, rValue ); } else { DBG_ERROR("Not implemented!"); return sal_False; } } sal_Bool SotStorageStream::GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue ) { UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pOwnStm ); if ( pStg ) { return pStg->GetProperty( rName, rValue ); } else { DBG_ERROR("Not implemented!"); return sal_False; } } ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SotStorageStream::GetXInputStream() const { UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pOwnStm ); if ( pStg ) { return pStg->GetXInputStream(); } else { DBG_ERROR("Not implemented!"); return ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >(); } } /************** class SotStorage ****************************************** *************************************************************************/ class SotStorageFactory : public SotFactory { public: TYPEINFO(); SotStorageFactory( const SvGlobalName & rName, const String & rClassName, CreateInstanceType pCreateFuncP ) : SotFactory( rName, rClassName, pCreateFuncP ) {} }; TYPEINIT1(SotStorageFactory,SotFactory); SO2_IMPL_BASIC_CLASS1_DLL(SotStorage,SotStorageFactory,SotObject, SvGlobalName( 0x980ce7e0, 0xf905, 0x11d0, 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) ) SO2_IMPL_INVARIANT(SotStorage) /************************************************************************ |* |* SotStorage::Tes*() |* |* Beschreibung *************************************************************************/ void SotStorage::TestMemberObjRef( sal_Bool /*bFree*/ ) { } #ifdef TEST_INVARIANT void SotStorage::TestMemberInvariant( sal_Bool /*bPrint*/ ) { } #endif /************************************************************************ |* |* SotStorage::SotStorage() |* |* Beschreibung Es muss ein I... Objekt an SvObject uebergeben |* werden, da es sonst selbst ein IUnknown anlegt und |* festlegt, dass alle weiteren I... Objekte mit |* delete zerstoert werden (Owner() == sal_True). |* Es werden aber nur IStorage Objekte benutzt und nicht |* selbst implementiert, deshalb wird so getan, als ob |* das IStorage Objekt von aussen kam und es wird mit |* Release() freigegeben. |* Die CreateStorage Methoden werden benoetigt, um |* ein IStorage Objekt vor dem Aufruf von SvObject |* zu erzeugen (Own, !Own automatik). |* Hat CreateStorage ein Objekt erzeugt, dann wurde |* der RefCounter schon um 1 erhoet. |* Die Uebergabe erfolgt in pStorageCTor. Die Variable |* ist NULL, wenn es nicht geklappt hat. |* Ersterstellung MM 23.06.94 |* Letzte Aenderung MM 23.06.94 |* *************************************************************************/ #define INIT_SotStorage() \ : m_pOwnStg( NULL ) \ , m_pStorStm( NULL ) \ , m_nError( SVSTREAM_OK ) \ , m_bIsRoot( sal_False ) \ , m_bDelStm( sal_False ) \ , m_nVersion( SOFFICE_FILEFORMAT_CURRENT ) SotStorage::SotStorage() INIT_SotStorage() { // ??? What's this ??? } #define ERASEMASK ( STREAM_TRUNC | STREAM_WRITE | STREAM_SHARE_DENYALL ) #include #include #include SotStorage::SotStorage( const ::ucbhelper::Content& rContent, const String & rName, StreamMode nMode, StorageMode nStorageMode ) INIT_SotStorage() { m_aName = rName; // Namen merken m_pOwnStg = new UCBStorage( rContent, m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); SetError( m_pOwnStg->GetError() ); if ( IsOLEStorage() ) m_nVersion = SOFFICE_FILEFORMAT_50; SignAsRoot( m_pOwnStg->IsRoot() ); } SotStorage::SotStorage( const String & rName, StreamMode nMode, StorageMode nStorageMode ) INIT_SotStorage() { m_aName = rName; // Namen merken CreateStorage( sal_True, nMode, nStorageMode ); if ( IsOLEStorage() ) m_nVersion = SOFFICE_FILEFORMAT_50; } void SotStorage::CreateStorage( sal_Bool bForceUCBStorage, StreamMode nMode, StorageMode nStorageMode ) { DBG_ASSERT( !m_pStorStm && !m_pOwnStg, "Use only in ctor!" ); if( m_aName.Len() ) { // named storage if( ( ( nMode & ERASEMASK ) == ERASEMASK ) ) ::utl::UCBContentHelper::Kill( m_aName ); INetURLObject aObj( m_aName ); if ( aObj.GetProtocol() == INET_PROT_NOT_VALID ) { String aURL; ::utl::LocalFileHelper::ConvertPhysicalNameToURL( m_aName, aURL ); aObj.SetURL( aURL ); m_aName = aObj.GetMainURL( INetURLObject::NO_DECODE ); } // a new unpacked storage should be created if ( nStorageMode == STORAGE_CREATE_UNPACKED ) { // don't open stream readwrite, content provider may not support this ! String aURL = UCBStorage::CreateLinkFile( m_aName ); if ( aURL.Len() ) { ::ucbhelper::Content aContent( aURL, ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XCommandEnvironment >() ); m_pOwnStg = new UCBStorage( aContent, aURL, nMode, sal_False ); } else { m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); SetError( ERRCODE_IO_NOTSUPPORTED ); } } else { // check the stream m_pStorStm = ::utl::UcbStreamHelper::CreateStream( m_aName, nMode ); if ( m_pStorStm && m_pStorStm->GetError() ) DELETEZ( m_pStorStm ); if ( m_pStorStm ) { // try as UCBStorage, next try as OLEStorage sal_Bool bIsUCBStorage = UCBStorage::IsStorageFile( m_pStorStm ); if ( !bIsUCBStorage && bForceUCBStorage ) // if UCBStorage has priority, it should not be used only if it is really an OLEStorage bIsUCBStorage = !Storage::IsStorageFile( m_pStorStm ); if ( bIsUCBStorage ) { if ( UCBStorage::GetLinkedFile( *m_pStorStm ).Len() ) { // detect special unpacked storages m_pOwnStg = new UCBStorage( *m_pStorStm, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); m_bDelStm = sal_True; } else { // detect special disk spanned storages if ( UCBStorage::IsDiskSpannedFile( m_pStorStm ) ) nMode |= STORAGE_DISKSPANNED_MODE; // UCBStorage always works directly on the UCB content, so discard the stream first DELETEZ( m_pStorStm ); m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); } } else { // OLEStorage can be opened with a stream m_pOwnStg = new Storage( *m_pStorStm, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); m_bDelStm = sal_True; } } else if ( bForceUCBStorage ) { m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); SetError( ERRCODE_IO_NOTSUPPORTED ); } else { m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); SetError( ERRCODE_IO_NOTSUPPORTED ); } } } else { // temporary storage if ( bForceUCBStorage ) m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); else m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); m_aName = m_pOwnStg->GetName(); } SetError( m_pOwnStg->GetError() ); SignAsRoot( m_pOwnStg->IsRoot() ); } SotStorage::SotStorage( sal_Bool bUCBStorage, const String & rName, StreamMode nMode, StorageMode nStorageMode ) INIT_SotStorage() { m_aName = rName; CreateStorage( bUCBStorage, nMode, nStorageMode ); if ( IsOLEStorage() ) m_nVersion = SOFFICE_FILEFORMAT_50; } SotStorage::SotStorage( BaseStorage * pStor ) INIT_SotStorage() { if ( pStor ) { m_aName = pStor->GetName(); // Namen merken SignAsRoot( pStor->IsRoot() ); SetError( pStor->GetError() ); } m_pOwnStg = pStor; sal_uLong nErr = m_pOwnStg ? m_pOwnStg->GetError() : SVSTREAM_CANNOT_MAKE; SetError( nErr ); if ( IsOLEStorage() ) m_nVersion = SOFFICE_FILEFORMAT_50; } SotStorage::SotStorage( sal_Bool bUCBStorage, SvStream & rStm ) INIT_SotStorage() { SetError( rStm.GetError() ); // try as UCBStorage, next try as OLEStorage if ( UCBStorage::IsStorageFile( &rStm ) || bUCBStorage ) m_pOwnStg = new UCBStorage( rStm, sal_False ); else m_pOwnStg = new Storage( rStm, sal_False ); SetError( m_pOwnStg->GetError() ); if ( IsOLEStorage() ) m_nVersion = SOFFICE_FILEFORMAT_50; SignAsRoot( m_pOwnStg->IsRoot() ); } SotStorage::SotStorage( SvStream & rStm ) INIT_SotStorage() { SetError( rStm.GetError() ); // try as UCBStorage, next try as OLEStorage if ( UCBStorage::IsStorageFile( &rStm ) ) m_pOwnStg = new UCBStorage( rStm, sal_False ); else m_pOwnStg = new Storage( rStm, sal_False ); SetError( m_pOwnStg->GetError() ); if ( IsOLEStorage() ) m_nVersion = SOFFICE_FILEFORMAT_50; SignAsRoot( m_pOwnStg->IsRoot() ); } SotStorage::SotStorage( SvStream * pStm, sal_Bool bDelete ) INIT_SotStorage() { SetError( pStm->GetError() ); // try as UCBStorage, next try as OLEStorage if ( UCBStorage::IsStorageFile( pStm ) ) m_pOwnStg = new UCBStorage( *pStm, sal_False ); else m_pOwnStg = new Storage( *pStm, sal_False ); SetError( m_pOwnStg->GetError() ); m_pStorStm = pStm; m_bDelStm = bDelete; if ( IsOLEStorage() ) m_nVersion = SOFFICE_FILEFORMAT_50; SignAsRoot( m_pOwnStg->IsRoot() ); } /************************************************************************* |* SotStorage::~SotStorage() |* |* Beschreibung *************************************************************************/ SotStorage::~SotStorage() { delete m_pOwnStg; if( m_bDelStm ) delete m_pStorStm; } /************************************************************************* |* SotStorage::RemoveUNOStorageHolder() |* |* Beschreibung *************************************************************************/ void SotStorage::RemoveUNOStorageHolder( UNOStorageHolder* pHolder ) { UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg ); if ( pStg ) { pStg->GetUNOStorageHolderList()->remove( pHolder ); pHolder->release(); } else { DBG_ERROR("Not implemented!"); } } /************************************************************************* |* SotStorage::GetUNOAPIDuplicate() |* |* Beschreibung *************************************************************************/ uno::Reference< embed::XStorage > SotStorage::GetUNOAPIDuplicate( const String& rEleName, sal_Int32 nUNOStorageMode ) { // after we create a duplicate we will register wrapper // for storage messages, the wrapper will control the real storage // the real storage will be able to ask the duplicate to dispose if it's parent is disposed uno::Reference< embed::XStorage > xResult; UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg ); if ( !pStg ) return xResult; UNOStorageHolderList* pUNOStorageHolderList = pStg->GetUNOStorageHolderList(); if ( !pUNOStorageHolderList ) return xResult; for ( UNOStorageHolderList::iterator aIter = pUNOStorageHolderList->begin(); aIter != pUNOStorageHolderList->end(); aIter++ ) if ( (*aIter) && (*aIter)->GetStorageName().Equals( rEleName ) ) { // the storage is already in use return xResult; } if ( IsStream( rEleName ) ) return xResult; if ( GetError() == ERRCODE_NONE ) { StreamMode nMode = ( ( nUNOStorageMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE ) ? STREAM_WRITE : ( STREAM_READ | STREAM_NOCREATE ); if ( nUNOStorageMode & embed::ElementModes::NOCREATE ) nMode |= STREAM_NOCREATE; sal_Bool bStorageReady = !IsStorage( rEleName ); SotStorageRef pChildStorage = OpenUCBStorage( rEleName, nMode, STORAGE_TRANSACTED ); if ( pChildStorage->GetError() == ERRCODE_NONE && pChildStorage->m_pOwnStg ) { ::utl::TempFile* pTempFile = new ::utl::TempFile(); if ( pTempFile->GetURL().Len() ) { if ( !bStorageReady ) { UCBStorage* pChildUCBStg = PTR_CAST( UCBStorage, pChildStorage->m_pOwnStg ); if ( pChildUCBStg ) { UCBStorage* pTempStorage = new UCBStorage( pTempFile->GetURL(), STREAM_WRITE, sal_False, sal_True ); if ( pTempStorage ) { pChildUCBStg->CopyTo( pTempStorage ); // CopyTo does not transport unknown media type // just workaround it uno::Any aMediaType; if ( pChildUCBStg->GetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType ) ) pTempStorage->SetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType ); bStorageReady = !pChildUCBStg->GetError() && !pTempStorage->GetError() && pTempStorage->Commit(); delete ((BaseStorage*)pTempStorage); pTempStorage = NULL; } } OSL_ENSURE( bStorageReady, "Problem on storage copy!\n" ); } if ( bStorageReady ) { try { uno::Reference< lang::XSingleServiceFactory > xStorageFactory( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ), uno::UNO_QUERY ); OSL_ENSURE( xStorageFactory.is(), "Can't create storage factory!\n" ); if ( xStorageFactory.is() ) { uno::Sequence< uno::Any > aArg( 2 ); aArg[0] <<= ::rtl::OUString( pTempFile->GetURL() ); aArg[1] <<= nUNOStorageMode; uno::Reference< embed::XStorage > xDuplStorage( xStorageFactory->createInstanceWithArguments( aArg ), uno::UNO_QUERY ); OSL_ENSURE( xDuplStorage.is(), "Can't open storage!\n" ); if ( xDuplStorage.is() ) { UNOStorageHolder* pHolder = new UNOStorageHolder( *this, *pChildStorage, xDuplStorage, pTempFile ); pHolder->acquire(); pTempFile = NULL; pUNOStorageHolderList->push_back( pHolder ); xResult = xDuplStorage; } } } catch( uno::Exception& e ) { (void)e; OSL_ENSURE( sal_False, ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ) ); } } } if ( pTempFile != NULL ) delete pTempFile; } else SetError( pChildStorage->GetError() ); } return xResult; } /************************************************************************* |* SotStorage::CreateMemoryStream() |* |* Beschreibung *************************************************************************/ SvMemoryStream * SotStorage::CreateMemoryStream() { SvMemoryStream * pStm = NULL; pStm = new SvMemoryStream( 0x8000, 0x8000 ); SotStorageRef aStg = new SotStorage( *pStm ); if( CopyTo( aStg ) ) aStg->Commit(); else { aStg.Clear(); // Storage vorher freigeben delete pStm; pStm = NULL; } return pStm; } /************************************************************************* |* SotStorage::GetStorage() |* |* Beschreibung *************************************************************************/ sal_Bool SotStorage::IsStorageFile( const String & rFileName ) { String aName( rFileName ); INetURLObject aObj( aName ); if ( aObj.GetProtocol() == INET_PROT_NOT_VALID ) { String aURL; ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL ); aObj.SetURL( aURL ); aName = aObj.GetMainURL( INetURLObject::NO_DECODE ); } SvStream * pStm = ::utl::UcbStreamHelper::CreateStream( aName, STREAM_STD_READ ); sal_Bool bRet = SotStorage::IsStorageFile( pStm ); delete pStm; return bRet; } sal_Bool SotStorage::IsStorageFile( SvStream* pStream ) { /** code for new storages must come first! **/ if ( pStream ) { long nPos = pStream->Tell(); sal_Bool bRet = UCBStorage::IsStorageFile( pStream ); if ( !bRet ) bRet = Storage::IsStorageFile( pStream ); pStream->Seek( nPos ); return bRet; } else return sal_False; } /************************************************************************* |* SotStorage::GetStorage() |* |* Beschreibung *************************************************************************/ const String & SotStorage::GetName() const { if( !m_aName.Len() ) { DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) ((SotStorage *)this)->m_aName = m_pOwnStg->GetName(); } return m_aName; } void SotStorage::SetName( const String& rName ) { // This method is necessary because most storages will not be opened with a FileName, but an external stream instead // This stream is a stream opened by a UCP and so aName is only used as a transport for all client code of the SotStorage // class that depends on the fact that a root storage has a name DBG_ASSERT( !GetName().Len(), "SetName() must not be called when the storage already has a name!" ); m_aName = rName; } /************************************************************************* |* SotStorage::ResetError() |* |* Beschreibung *************************************************************************/ void SotStorage::ResetError() { m_nError = SVSTREAM_OK; if( m_pOwnStg ) m_pOwnStg->ResetError(); } /************************************************************************* |* SotStorage::SetClass() |* SotStorage::SetConvertClass() |* |* Beschreibung *************************************************************************/ void SotStorage::SetClass( const SvGlobalName & rName, sal_uLong nOriginalClipFormat, const String & rUserTypeName ) { DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) m_pOwnStg->SetClass( rName, nOriginalClipFormat, rUserTypeName ); else SetError( SVSTREAM_GENERALERROR ); } void SotStorage::SetConvertClass( const SvGlobalName & rName, sal_uLong nOriginalClipFormat, const String & rUserTypeName ) { DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) m_pOwnStg->SetConvertClass( rName, nOriginalClipFormat, rUserTypeName ); else SetError( SVSTREAM_GENERALERROR ); } /************************************************************************* |* SotStorage::GetClassName() |* SotStorage::GetFormat() |* SotStorage::GetUserName() |* SotStorage::ShouldConvert() |* |* Beschreibung *************************************************************************/ SvGlobalName SotStorage::GetClassName() { SvGlobalName aGN; DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) aGN = m_pOwnStg->GetClassName(); else SetError( SVSTREAM_GENERALERROR ); return aGN; } sal_uLong SotStorage::GetFormat() { sal_uLong nFormat = 0; DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) nFormat = m_pOwnStg->GetFormat(); else SetError( SVSTREAM_GENERALERROR ); return nFormat; } String SotStorage::GetUserName() { String aName; DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) aName = m_pOwnStg->GetUserName(); else SetError( SVSTREAM_GENERALERROR ); return aName; } sal_Bool SotStorage::ShouldConvert() { DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) return m_pOwnStg->ShouldConvert(); else SetError( SVSTREAM_GENERALERROR ); return sal_False; } /************************************************************************* |* SotStorage::FillInfoList() |* |* Beschreibung *************************************************************************/ void SotStorage::FillInfoList( SvStorageInfoList * pFillList ) const { DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) m_pOwnStg->FillInfoList( pFillList ); } /************************************************************************* |* SotStorage::CopyTo() |* |* Beschreibung *************************************************************************/ sal_Bool SotStorage::CopyTo( SotStorage * pDestStg ) { DBG_ASSERT( Owner(), "must be owner" ); DBG_ASSERT( pDestStg->Owner(), "must be owner" ); if( m_pOwnStg && pDestStg->m_pOwnStg ) { m_pOwnStg->CopyTo( pDestStg->m_pOwnStg ); SetError( m_pOwnStg->GetError() ); pDestStg->m_aKey = m_aKey; pDestStg->m_nVersion = m_nVersion; } else SetError( SVSTREAM_GENERALERROR ); return SVSTREAM_OK == GetError(); } /************************************************************************* |* SotStorage::Commit() |* |* Beschreibung *************************************************************************/ sal_Bool SotStorage::Commit() { DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) { if( !m_pOwnStg->Commit() ) SetError( m_pOwnStg->GetError() ); } else SetError( SVSTREAM_GENERALERROR ); return SVSTREAM_OK == GetError(); } /************************************************************************* |* SotStorage::Revert() |* |* Beschreibung *************************************************************************/ sal_Bool SotStorage::Revert() { DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) { if( !m_pOwnStg->Revert() ) SetError( m_pOwnStg->GetError() ); } else SetError( SVSTREAM_GENERALERROR ); return SVSTREAM_OK == GetError(); } /************************************************************************* |* SotStorage::OpenStream() |* |* Beschreibung *************************************************************************/ SotStorageStream * SotStorage::OpenEncryptedSotStream( const String & rEleName, const ByteString& rKey, StreamMode nMode, StorageMode nStorageMode ) { DBG_ASSERT( !nStorageMode, "StorageModes ignored" ); SotStorageStream * pStm = NULL; DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) { // volle Ole-Patches einschalten // egal was kommt, nur exclusiv gestattet nMode |= STREAM_SHARE_DENYALL; ErrCode nE = m_pOwnStg->GetError(); BaseStorageStream* p = m_pOwnStg->OpenStream( rEleName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True, &rKey ); pStm = new SotStorageStream( p ); if( !nE ) m_pOwnStg->ResetError(); // kein Fehler setzen if( nMode & STREAM_TRUNC ) pStm->SetSize( 0 ); } else SetError( SVSTREAM_GENERALERROR ); return pStm; } SotStorageStream * SotStorage::OpenSotStream( const String & rEleName, StreamMode nMode, StorageMode nStorageMode ) { DBG_ASSERT( !nStorageMode, "StorageModes ignored" ); SotStorageStream * pStm = NULL; DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) { // volle Ole-Patches einschalten // egal was kommt, nur exclusiv gestattet nMode |= STREAM_SHARE_DENYALL; ErrCode nE = m_pOwnStg->GetError(); BaseStorageStream * p = m_pOwnStg->OpenStream( rEleName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); pStm = new SotStorageStream( p ); if( !nE ) m_pOwnStg->ResetError(); // kein Fehler setzen if( nMode & STREAM_TRUNC ) pStm->SetSize( 0 ); } else SetError( SVSTREAM_GENERALERROR ); return pStm; } /************************************************************************* |* SotStorage::OpenStorage() |* |* Beschreibung *************************************************************************/ SotStorage * SotStorage::OpenSotStorage( const String & rEleName, StreamMode nMode, StorageMode nStorageMode ) { SotStorage * pStor = NULL; DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) { nMode |= STREAM_SHARE_DENYALL; ErrCode nE = m_pOwnStg->GetError(); BaseStorage * p = m_pOwnStg->OpenStorage( rEleName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); if( p ) { pStor = new SotStorage( p ); if( !nE ) m_pOwnStg->ResetError(); // kein Fehler setzen return pStor; } } SetError( SVSTREAM_GENERALERROR ); return NULL; } SotStorage * SotStorage::OpenUCBStorage( const String & rEleName, StreamMode nMode, StorageMode nStorageMode ) { SotStorage * pStor = NULL; DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) { nMode |= STREAM_SHARE_DENYALL; ErrCode nE = m_pOwnStg->GetError(); BaseStorage * p = m_pOwnStg->OpenUCBStorage( rEleName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); pStor = new SotStorage( p ); if( !nE ) m_pOwnStg->ResetError(); // kein Fehler setzen } else SetError( SVSTREAM_GENERALERROR ); return pStor; } SotStorage * SotStorage::OpenOLEStorage( const String & rEleName, StreamMode nMode, StorageMode nStorageMode ) { SotStorage * pStor = NULL; DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) { nMode |= STREAM_SHARE_DENYALL; ErrCode nE = m_pOwnStg->GetError(); BaseStorage * p = m_pOwnStg->OpenOLEStorage( rEleName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? sal_False : sal_True ); pStor = new SotStorage( p ); if( !nE ) m_pOwnStg->ResetError(); // kein Fehler setzen } else SetError( SVSTREAM_GENERALERROR ); return pStor; } /************************************************************************* |* SotStorage::IsStream() |* SotStorage::IsStorage() |* SotStorage::IsContained() |* |* Beschreibung *************************************************************************/ sal_Bool SotStorage::IsStorage( const String & rEleName ) const { DBG_ASSERT( Owner(), "must be owner" ); // ein bisschen schneller if( m_pOwnStg ) return m_pOwnStg->IsStorage( rEleName ); return sal_False; } sal_Bool SotStorage::IsStream( const String & rEleName ) const { DBG_ASSERT( Owner(), "must be owner" ); // ein bisschen schneller if( m_pOwnStg ) return m_pOwnStg->IsStream( rEleName ); return sal_False; } sal_Bool SotStorage::IsContained( const String & rEleName ) const { DBG_ASSERT( Owner(), "must be owner" ); // ein bisschen schneller if( m_pOwnStg ) return m_pOwnStg->IsContained( rEleName ); return sal_False; } /************************************************************************* |* SotStorage::Remove() |* |* Beschreibung *************************************************************************/ sal_Bool SotStorage::Remove( const String & rEleName ) { DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) { m_pOwnStg->Remove( rEleName ); SetError( m_pOwnStg->GetError() ); } else SetError( SVSTREAM_GENERALERROR ); return SVSTREAM_OK == GetError(); } /************************************************************************* |* SotStorage::Rename() |* |* Beschreibung *************************************************************************/ sal_Bool SotStorage::Rename( const String & rEleName, const String & rNewName ) { DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) { m_pOwnStg->Rename( rEleName, rNewName ); SetError( m_pOwnStg->GetError() ); } else SetError( SVSTREAM_GENERALERROR ); return SVSTREAM_OK == GetError(); } /************************************************************************* |* SotStorage::CopyTo() |* |* Beschreibung *************************************************************************/ sal_Bool SotStorage::CopyTo( const String & rEleName, SotStorage * pNewSt, const String & rNewName ) { DBG_ASSERT( Owner(), "must be owner" ); DBG_ASSERT( pNewSt->Owner(), "must be owner" ); if( m_pOwnStg ) { m_pOwnStg->CopyTo( rEleName, pNewSt->m_pOwnStg, rNewName ); SetError( m_pOwnStg->GetError() ); SetError( pNewSt->GetError() ); } else SetError( SVSTREAM_GENERALERROR ); return SVSTREAM_OK == GetError(); } /************************************************************************* |* SotStorage::MoveTo() |* |* Beschreibung *************************************************************************/ sal_Bool SotStorage::MoveTo( const String & rEleName, SotStorage * pNewSt, const String & rNewName ) { DBG_ASSERT( Owner(), "must be owner" ); DBG_ASSERT( pNewSt->Owner(), "must be owner" ); if( m_pOwnStg ) { m_pOwnStg->MoveTo( rEleName, pNewSt->m_pOwnStg, rNewName ); SetError( m_pOwnStg->GetError() ); SetError( pNewSt->GetError() ); } else SetError( SVSTREAM_GENERALERROR ); return SVSTREAM_OK == GetError(); } const SvStream* SotStorage::GetSvStream() { const SvStream* pResult = 0; DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) pResult = m_pOwnStg->GetSvStream(); return pResult; } SvStream* SotStorage::GetTargetSvStream() const { SvStream* pResult = 0; DBG_ASSERT( Owner(), "must be owner" ); if( m_pOwnStg ) pResult = (SvStream*)(m_pOwnStg->GetSvStream()); return pResult; } sal_Bool SotStorage::Validate() { DBG_ASSERT( m_bIsRoot, "Validate nur an Rootstorage" ); if( m_pOwnStg ) return m_pOwnStg->ValidateFAT(); else return sal_True; } sal_Bool SotStorage::SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue ) { UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg ); if ( pStg ) { return pStg->SetProperty( rName, rValue ); } else { DBG_WARNING("W1:Not implemented!"); return sal_False; } } sal_Bool SotStorage::GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue ) { UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg ); if ( pStg ) { return pStg->GetProperty( rName, rValue ); } else if ( rName.CompareToAscii("MediaType") == COMPARE_EQUAL ) { String aStr = SotExchange::GetFormatMimeType( GetFormat() ); sal_uInt16 nPos = aStr.Search(';'); if ( nPos != STRING_NOTFOUND ) aStr = aStr.Copy( 0, nPos ); rValue <<= (::rtl::OUString) aStr; return sal_True; } else { DBG_WARNING("W1:Not implemented!"); return sal_False; } } sal_Bool SotStorage::GetProperty( const String& rEleName, const String& rName, ::com::sun::star::uno::Any& rValue ) { UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg ); if ( pStg ) { return pStg->GetProperty( rEleName, rName, rValue ); } else { DBG_WARNING("W1:Not implemented!"); return sal_False; } } sal_Bool SotStorage::IsOLEStorage() const { UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg ); return !pStg; } sal_Bool SotStorage::IsOLEStorage( const String & rFileName ) { return Storage::IsStorageFile( rFileName ); } sal_Bool SotStorage::IsOLEStorage( SvStream* pStream ) { return Storage::IsStorageFile( pStream ); } void SotStorage::SetKey( const ByteString& rKey ) { m_aKey = rKey; if ( !IsOLEStorage() ) { sal_uInt8 aBuffer[RTL_DIGEST_LENGTH_SHA1]; rtlDigestError nError = rtl_digest_SHA1( m_aKey.GetBuffer(), m_aKey.Len(), aBuffer, RTL_DIGEST_LENGTH_SHA1 ); if ( nError == rtl_Digest_E_None ) { sal_uInt8* pBuffer = aBuffer; ::com::sun::star::uno::Sequence < sal_Int8 > aSequ( (sal_Int8*) pBuffer, RTL_DIGEST_LENGTH_SHA1 ); ::com::sun::star::uno::Any aAny; aAny <<= aSequ; SetProperty( ::rtl::OUString::createFromAscii("EncryptionKey"), aAny ); } } } SotStorage* SotStorage::OpenOLEStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage, const String& rEleName, StreamMode nMode ) { sal_Int32 nEleMode = embed::ElementModes::SEEKABLEREAD; if ( nMode & STREAM_WRITE ) nEleMode |= embed::ElementModes::WRITE; if ( nMode & STREAM_TRUNC ) nEleMode |= embed::ElementModes::TRUNCATE; if ( nMode & STREAM_NOCREATE ) nEleMode |= embed::ElementModes::NOCREATE; SvStream* pStream = NULL; try { uno::Reference < io::XStream > xStream = xStorage->openStreamElement( rEleName, nEleMode ); // TODO/LATER: should it be done this way? if ( nMode & STREAM_WRITE ) { uno::Reference < beans::XPropertySet > xStreamProps( xStream, uno::UNO_QUERY_THROW ); xStreamProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) ); } pStream = utl::UcbStreamHelper::CreateStream( xStream ); } catch ( uno::Exception& ) { //TODO/LATER: ErrorHandling pStream = new SvMemoryStream; pStream->SetError( ERRCODE_IO_GENERAL ); } return new SotStorage( pStream, sal_True ); } sal_Int32 SotStorage::GetFormatID( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage ) { uno::Reference< beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY ); if ( !xProps.is() ) return 0; ::rtl::OUString aMediaType; xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType; if ( aMediaType.getLength() ) { ::com::sun::star::datatransfer::DataFlavor aDataFlavor; aDataFlavor.MimeType = aMediaType; return SotExchange::GetFormat( aDataFlavor ); } return 0; } sal_Int32 SotStorage::GetVersion( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage ) { sal_Int32 nSotFormatID = SotStorage::GetFormatID( xStorage ); switch( nSotFormatID ) { case SOT_FORMATSTR_ID_STARWRITER_8: case SOT_FORMATSTR_ID_STARWRITER_8_TEMPLATE: case SOT_FORMATSTR_ID_STARWRITERWEB_8: case SOT_FORMATSTR_ID_STARWRITERGLOB_8: case SOT_FORMATSTR_ID_STARDRAW_8: case SOT_FORMATSTR_ID_STARDRAW_8_TEMPLATE: case SOT_FORMATSTR_ID_STARIMPRESS_8: case SOT_FORMATSTR_ID_STARIMPRESS_8_TEMPLATE: case SOT_FORMATSTR_ID_STARCALC_8: case SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE: case SOT_FORMATSTR_ID_STARCHART_8: case SOT_FORMATSTR_ID_STARCHART_8_TEMPLATE: case SOT_FORMATSTR_ID_STARMATH_8: case SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE: return SOFFICE_FILEFORMAT_8; case SOT_FORMATSTR_ID_STARWRITER_60: case SOT_FORMATSTR_ID_STARWRITERWEB_60: case SOT_FORMATSTR_ID_STARWRITERGLOB_60: case SOT_FORMATSTR_ID_STARDRAW_60: case SOT_FORMATSTR_ID_STARIMPRESS_60: case SOT_FORMATSTR_ID_STARCALC_60: case SOT_FORMATSTR_ID_STARCHART_60: case SOT_FORMATSTR_ID_STARMATH_60: return SOFFICE_FILEFORMAT_60; } return 0; }