1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: storage.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sot.hxx"
33 #include <com/sun/star/uno/Sequence.hxx>
34 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
35 #include <com/sun/star/embed/XStorage.hpp>
36 #include <com/sun/star/embed/ElementModes.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <rtl/digest.h>
40 #include <osl/file.hxx>
42 #include <storinfo.hxx>
43 #include <sot/storage.hxx>
44 #include <sot/formats.hxx>
45 #include <sot/exchange.hxx>
46 #include <unotools/ucbstreamhelper.hxx>
47 #ifndef _TOOLS_FSYS_HXX
48 #include <tools/fsys.hxx>
50 #include <tools/cachestr.hxx>
51 #include <tools/debug.hxx>
52 #include <tools/urlobj.hxx>
53 #include <unotools/localfilehelper.hxx>
54 #include <unotools/ucbhelper.hxx>
55 #include <comphelper/processfactory.hxx>
57 #include "unostorageholder.hxx"
59 using namespace ::com::sun::star
;
61 /************** class SotStorageStream ***********************************/
62 class SotStorageStreamFactory
: public SotFactory
66 SotStorageStreamFactory( const SvGlobalName
& rName
,
67 const String
& rClassName
,
68 CreateInstanceType pCreateFuncP
)
69 : SotFactory( rName
, rClassName
, pCreateFuncP
)
72 TYPEINIT1(SotStorageStreamFactory
,SotFactory
);
75 SO2_IMPL_BASIC_CLASS1_DLL(SotStorageStream
,SotStorageStreamFactory
,SotObject
,
76 SvGlobalName( 0xd7deb420, 0xf902, 0x11d0,
77 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
78 SO2_IMPL_INVARIANT(SotStorageStream
)
81 void SotStorageStream::TestMemberObjRef( BOOL
/*bFree*/ )
86 void SotStorageStream::TestMemberInvariant( BOOL
/*bPrint*/ )
91 /************************************************************************
92 |* SotStorageStream::SotStorageStream()
95 *************************************************************************/
96 SvLockBytesRef
MakeLockBytes_Impl( const String
& rName
, StreamMode nMode
)
101 SvStream
* pFileStm
= new SvFileStream( rName
, nMode
);
102 xLB
= new SvLockBytes( pFileStm
, TRUE
);
106 SvStream
* pCacheStm
= new SvCacheStream();
107 xLB
= new SvLockBytes( pCacheStm
, TRUE
);
112 SotStorageStream::SotStorageStream( const String
& rName
, StreamMode nMode
,
118 : SvStream( MakeLockBytes_Impl( rName
, nMode
) )
121 if( nMode
& STREAM_WRITE
)
126 DBG_ASSERT( !nStorageMode
,"StorageModes ignored" );
129 SotStorageStream::SotStorageStream( BaseStorageStream
* pStm
)
133 if( STREAM_WRITE
& pStm
->GetMode() )
139 SetError( pStm
->GetError() );
146 SetError( SVSTREAM_INVALID_PARAMETER
);
150 SotStorageStream::SotStorageStream()
153 // ??? wenn Init virtuell ist, entsprechen setzen
157 /************************************************************************
158 |* SotStorageStream::~SotStorageStream()
161 *************************************************************************/
162 SotStorageStream::~SotStorageStream()
164 Flush(); //SetBufferSize(0);
168 /*************************************************************************
169 |* SotStorageStream::SyncSvStream()
171 |* Beschreibung: Der SvStream wird auf den Zustand des Standard-Streams
172 |* gesetzt. Der Puffer des SvStreams wird weggeworfen.
173 *************************************************************************/
174 void SotStorageStream::SyncSvStream()
180 nPos
= pOwnStm
->Tell();
181 SetError( pOwnStm
->GetError() );
182 SvStream::SyncSvStream( nPos
);
186 /*************************************************************************
187 |* SotStorageStream::ResetError()
190 *************************************************************************/
191 void SotStorageStream::ResetError()
193 SvStream::ResetError();
195 pOwnStm
->ResetError();
198 /*************************************************************************
199 |* SotStorageStream::GetData()
202 *************************************************************************/
203 ULONG
SotStorageStream::GetData( void* pData
, ULONG nSize
)
209 nRet
= pOwnStm
->Read( pData
, nSize
);
210 SetError( pOwnStm
->GetError() );
213 nRet
= SvStream::GetData( (sal_Char
*)pData
, nSize
);
217 /*************************************************************************
218 |* SotStorageStream::PutData()
221 *************************************************************************/
222 ULONG
SotStorageStream::PutData( const void* pData
, ULONG nSize
)
228 nRet
= pOwnStm
->Write( pData
, nSize
);
229 SetError( pOwnStm
->GetError() );
232 nRet
= SvStream::PutData( (sal_Char
*)pData
, nSize
);
236 /*************************************************************************
237 |* SotStorageStream::SeekPos()
240 *************************************************************************/
241 ULONG
SotStorageStream::SeekPos( ULONG nPos
)
247 nRet
= pOwnStm
->Seek( nPos
);
248 SetError( pOwnStm
->GetError() );
251 nRet
= SvStream::SeekPos( nPos
);
255 /*************************************************************************
256 |* SotStorageStream::Flush()
259 *************************************************************************/
260 void SotStorageStream::FlushData()
265 SetError( pOwnStm
->GetError() );
268 SvStream::FlushData();
271 /*************************************************************************
272 |* SotStorageStream::SetSize()
275 *************************************************************************/
276 void SotStorageStream::SetSize( ULONG nNewSize
)
281 pOwnStm
->SetSize( nNewSize
);
282 SetError( pOwnStm
->GetError() );
285 SvStream::SetSize( nNewSize
);
287 if( nNewSize
< nPos
)
291 //return GetError() == SVSTREAM_OK;
294 /*************************************************************************
296 |* SotStorageStream::GetSize()
300 *************************************************************************/
301 UINT32
SotStorageStream::GetSize() const
304 ((SotStorageStream
*)this)->Seek( STREAM_SEEK_TO_END
);
305 ULONG nSize
= Tell();
306 ((SotStorageStream
*)this)->Seek( nPos
);
310 /*************************************************************************
311 |* SotStorageStream::CopyTo()
314 *************************************************************************/
315 BOOL
SotStorageStream::CopyTo( SotStorageStream
* pDestStm
)
317 Flush(); // alle Daten schreiben
318 pDestStm
->ClearBuffer();
319 if( !pOwnStm
|| !pDestStm
->pOwnStm
)
320 { // Wenn Ole2 oder nicht nur eigene StorageStreams
322 ULONG nPos
= Tell(); // Position merken
324 pDestStm
->SetSize( 0 ); // Ziel-Stream leeren
326 void * pMem
= new BYTE
[ 8192 ];
328 while( 0 != (nRead
= Read( pMem
, 8192 )) )
330 if( nRead
!= pDestStm
->Write( pMem
, nRead
) )
332 SetError( SVSTREAM_GENERALERROR
);
336 delete [] static_cast<BYTE
*>(pMem
);
338 pDestStm
->Seek( nPos
);
345 nErr = pObjI->CopyTo( pDestStm->pObjI, uSize, NULL, &uWrite );
346 if( SUCCEEDED( nErr ) )
348 // Ziel-Streamzeiger steht hinter den Daten
350 pDestStm->Seek( uWrite.LowPart );
352 else if( GetScode( nErr ) == E_NOTIMPL )
353 { // Eines Tages werden alle MS... ?!#
355 pOwnStm
->CopyTo( pDestStm
->pOwnStm
);
356 SetError( pOwnStm
->GetError() );
358 return GetError() == SVSTREAM_OK
;
361 /*************************************************************************
362 |* SotStorageStream::Commit()
363 |* SotStorageStream::Revert()
366 *************************************************************************/
367 BOOL
SotStorageStream::Commit()
372 if( pOwnStm
->GetError() == SVSTREAM_OK
)
374 SetError( pOwnStm
->GetError() );
376 return GetError() == SVSTREAM_OK
;
379 BOOL
SotStorageStream::Revert()
384 SetError( pOwnStm
->GetError() );
386 return GetError() == SVSTREAM_OK
;
389 BOOL
SotStorageStream::SetProperty( const String
& rName
, const ::com::sun::star::uno::Any
& rValue
)
391 UCBStorageStream
* pStg
= PTR_CAST( UCBStorageStream
, pOwnStm
);
394 return pStg
->SetProperty( rName
, rValue
);
398 DBG_ERROR("Not implemented!");
403 BOOL
SotStorageStream::GetProperty( const String
& rName
, ::com::sun::star::uno::Any
& rValue
)
405 UCBStorageStream
* pStg
= PTR_CAST( UCBStorageStream
, pOwnStm
);
408 return pStg
->GetProperty( rName
, rValue
);
412 DBG_ERROR("Not implemented!");
417 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XInputStream
> SotStorageStream::GetXInputStream() const
419 UCBStorageStream
* pStg
= PTR_CAST( UCBStorageStream
, pOwnStm
);
422 return pStg
->GetXInputStream();
426 DBG_ERROR("Not implemented!");
427 return ::com::sun::star::uno::Reference
< ::com::sun::star::io::XInputStream
>();
433 /************** class SotStorage ******************************************
434 *************************************************************************/
435 class SotStorageFactory
: public SotFactory
439 SotStorageFactory( const SvGlobalName
& rName
,
440 const String
& rClassName
,
441 CreateInstanceType pCreateFuncP
)
442 : SotFactory( rName
, rClassName
, pCreateFuncP
)
445 TYPEINIT1(SotStorageFactory
,SotFactory
);
448 SO2_IMPL_BASIC_CLASS1_DLL(SotStorage
,SotStorageFactory
,SotObject
,
449 SvGlobalName( 0x980ce7e0, 0xf905, 0x11d0,
450 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
451 SO2_IMPL_INVARIANT(SotStorage
)
454 /************************************************************************
456 |* SotStorage::Tes*()
459 *************************************************************************/
460 void SotStorage::TestMemberObjRef( BOOL
/*bFree*/ )
464 #ifdef TEST_INVARIANT
465 void SotStorage::TestMemberInvariant( BOOL
/*bPrint*/ )
470 /************************************************************************
472 |* SotStorage::SotStorage()
474 |* Beschreibung Es muss ein I... Objekt an SvObject uebergeben
475 |* werden, da es sonst selbst ein IUnknown anlegt und
476 |* festlegt, dass alle weiteren I... Objekte mit
477 |* delete zerstoert werden (Owner() == TRUE).
478 |* Es werden aber nur IStorage Objekte benutzt und nicht
479 |* selbst implementiert, deshalb wird so getan, als ob
480 |* das IStorage Objekt von aussen kam und es wird mit
481 |* Release() freigegeben.
482 |* Die CreateStorage Methoden werden benoetigt, um
483 |* ein IStorage Objekt vor dem Aufruf von SvObject
484 |* zu erzeugen (Own, !Own automatik).
485 |* Hat CreateStorage ein Objekt erzeugt, dann wurde
486 |* der RefCounter schon um 1 erhoet.
487 |* Die Uebergabe erfolgt in pStorageCTor. Die Variable
488 |* ist NULL, wenn es nicht geklappt hat.
489 |* Ersterstellung MM 23.06.94
490 |* Letzte Aenderung MM 23.06.94
492 *************************************************************************/
493 #define INIT_SotStorage() \
494 : m_pOwnStg( NULL ) \
495 , m_pStorStm( NULL ) \
496 , m_nError( SVSTREAM_OK ) \
497 , m_bIsRoot( FALSE ) \
498 , m_bDelStm( FALSE ) \
499 , m_nVersion( SOFFICE_FILEFORMAT_CURRENT )
501 SotStorage::SotStorage()
504 // ??? What's this ???
507 #define ERASEMASK ( STREAM_TRUNC | STREAM_WRITE | STREAM_SHARE_DENYALL )
508 #include <com/sun/star/uno/Reference.h>
509 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
510 #include <ucbhelper/content.hxx>
512 SotStorage::SotStorage( const ::ucbhelper::Content
& rContent
, const String
& rName
, StreamMode nMode
, StorageMode nStorageMode
)
515 m_aName
= rName
; // Namen merken
516 m_pOwnStg
= new UCBStorage( rContent
, m_aName
, nMode
, (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
518 SetError( m_pOwnStg
->GetError() );
520 if ( IsOLEStorage() )
521 m_nVersion
= SOFFICE_FILEFORMAT_50
;
523 SignAsRoot( m_pOwnStg
->IsRoot() );
526 SotStorage::SotStorage( const String
& rName
, StreamMode nMode
, StorageMode nStorageMode
)
529 m_aName
= rName
; // Namen merken
530 CreateStorage( TRUE
, nMode
, nStorageMode
);
531 if ( IsOLEStorage() )
532 m_nVersion
= SOFFICE_FILEFORMAT_50
;
535 void SotStorage::CreateStorage( BOOL bForceUCBStorage
, StreamMode nMode
, StorageMode nStorageMode
)
537 DBG_ASSERT( !m_pStorStm
&& !m_pOwnStg
, "Use only in ctor!" );
541 if( ( ( nMode
& ERASEMASK
) == ERASEMASK
) )
542 ::utl::UCBContentHelper::Kill( m_aName
);
544 INetURLObject
aObj( m_aName
);
545 if ( aObj
.GetProtocol() == INET_PROT_NOT_VALID
)
548 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( m_aName
, aURL
);
550 m_aName
= aObj
.GetMainURL( INetURLObject::NO_DECODE
);
553 // a new unpacked storage should be created
554 if ( nStorageMode
== STORAGE_CREATE_UNPACKED
)
556 // don't open stream readwrite, content provider may not support this !
557 String aURL
= UCBStorage::CreateLinkFile( m_aName
);
560 ::ucbhelper::Content
aContent( aURL
, ::com::sun::star::uno::Reference
< ::com::sun::star::ucb::XCommandEnvironment
>() );
561 m_pOwnStg
= new UCBStorage( aContent
, aURL
, nMode
, FALSE
);
565 m_pOwnStg
= new Storage( m_aName
, nMode
, (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
566 SetError( ERRCODE_IO_NOTSUPPORTED
);
572 m_pStorStm
= ::utl::UcbStreamHelper::CreateStream( m_aName
, nMode
);
573 if ( m_pStorStm
&& m_pStorStm
->GetError() )
574 DELETEZ( m_pStorStm
);
578 // try as UCBStorage, next try as OLEStorage
579 BOOL bIsUCBStorage
= UCBStorage::IsStorageFile( m_pStorStm
);
580 if ( !bIsUCBStorage
&& bForceUCBStorage
)
581 // if UCBStorage has priority, it should not be used only if it is really an OLEStorage
582 bIsUCBStorage
= !Storage::IsStorageFile( m_pStorStm
);
586 if ( UCBStorage::GetLinkedFile( *m_pStorStm
).Len() )
588 // detect special unpacked storages
589 m_pOwnStg
= new UCBStorage( *m_pStorStm
, (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
594 // detect special disk spanned storages
595 if ( UCBStorage::IsDiskSpannedFile( m_pStorStm
) )
596 nMode
|= STORAGE_DISKSPANNED_MODE
;
598 // UCBStorage always works directly on the UCB content, so discard the stream first
599 DELETEZ( m_pStorStm
);
600 m_pOwnStg
= new UCBStorage( m_aName
, nMode
, (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
605 // OLEStorage can be opened with a stream
606 m_pOwnStg
= new Storage( *m_pStorStm
, (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
610 else if ( bForceUCBStorage
)
612 m_pOwnStg
= new UCBStorage( m_aName
, nMode
, (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
613 SetError( ERRCODE_IO_NOTSUPPORTED
);
617 m_pOwnStg
= new Storage( m_aName
, nMode
, (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
618 SetError( ERRCODE_IO_NOTSUPPORTED
);
625 if ( bForceUCBStorage
)
626 m_pOwnStg
= new UCBStorage( m_aName
, nMode
, (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
628 m_pOwnStg
= new Storage( m_aName
, nMode
, (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
629 m_aName
= m_pOwnStg
->GetName();
632 SetError( m_pOwnStg
->GetError() );
634 SignAsRoot( m_pOwnStg
->IsRoot() );
637 SotStorage::SotStorage( BOOL bUCBStorage
, const String
& rName
, StreamMode nMode
, StorageMode nStorageMode
)
641 CreateStorage( bUCBStorage
, nMode
, nStorageMode
);
642 if ( IsOLEStorage() )
643 m_nVersion
= SOFFICE_FILEFORMAT_50
;
646 SotStorage::SotStorage( BaseStorage
* pStor
)
651 m_aName
= pStor
->GetName(); // Namen merken
652 SignAsRoot( pStor
->IsRoot() );
653 SetError( pStor
->GetError() );
657 ULONG nErr
= m_pOwnStg
? m_pOwnStg
->GetError() : SVSTREAM_CANNOT_MAKE
;
659 if ( IsOLEStorage() )
660 m_nVersion
= SOFFICE_FILEFORMAT_50
;
663 SotStorage::SotStorage( BOOL bUCBStorage
, SvStream
& rStm
)
666 SetError( rStm
.GetError() );
668 // try as UCBStorage, next try as OLEStorage
669 if ( UCBStorage::IsStorageFile( &rStm
) || bUCBStorage
)
670 m_pOwnStg
= new UCBStorage( rStm
, FALSE
);
672 m_pOwnStg
= new Storage( rStm
, FALSE
);
674 SetError( m_pOwnStg
->GetError() );
676 if ( IsOLEStorage() )
677 m_nVersion
= SOFFICE_FILEFORMAT_50
;
679 SignAsRoot( m_pOwnStg
->IsRoot() );
682 SotStorage::SotStorage( SvStream
& rStm
)
685 SetError( rStm
.GetError() );
687 // try as UCBStorage, next try as OLEStorage
688 if ( UCBStorage::IsStorageFile( &rStm
) )
689 m_pOwnStg
= new UCBStorage( rStm
, FALSE
);
691 m_pOwnStg
= new Storage( rStm
, FALSE
);
693 SetError( m_pOwnStg
->GetError() );
695 if ( IsOLEStorage() )
696 m_nVersion
= SOFFICE_FILEFORMAT_50
;
698 SignAsRoot( m_pOwnStg
->IsRoot() );
701 SotStorage::SotStorage( SvStream
* pStm
, BOOL bDelete
)
704 SetError( pStm
->GetError() );
706 // try as UCBStorage, next try as OLEStorage
707 if ( UCBStorage::IsStorageFile( pStm
) )
708 m_pOwnStg
= new UCBStorage( *pStm
, FALSE
);
710 m_pOwnStg
= new Storage( *pStm
, FALSE
);
712 SetError( m_pOwnStg
->GetError() );
716 if ( IsOLEStorage() )
717 m_nVersion
= SOFFICE_FILEFORMAT_50
;
719 SignAsRoot( m_pOwnStg
->IsRoot() );
722 /*************************************************************************
723 |* SotStorage::~SotStorage()
726 *************************************************************************/
727 SotStorage::~SotStorage()
734 /*************************************************************************
735 |* SotStorage::RemoveUNOStorageHolder()
738 *************************************************************************/
739 void SotStorage::RemoveUNOStorageHolder( UNOStorageHolder
* pHolder
)
741 UCBStorage
* pStg
= PTR_CAST( UCBStorage
, m_pOwnStg
);
744 pStg
->GetUNOStorageHolderList()->remove( pHolder
);
749 DBG_ERROR("Not implemented!");
753 /*************************************************************************
754 |* SotStorage::GetUNOAPIDuplicate()
757 *************************************************************************/
758 uno::Reference
< embed::XStorage
> SotStorage::GetUNOAPIDuplicate( const String
& rEleName
, sal_Int32 nUNOStorageMode
)
760 // after we create a duplicate we will register wrapper
761 // for storage messages, the wrapper will control the real storage
762 // the real storage will be able to ask the duplicate to dispose if it's parent is disposed
764 uno::Reference
< embed::XStorage
> xResult
;
766 UCBStorage
* pStg
= PTR_CAST( UCBStorage
, m_pOwnStg
);
770 UNOStorageHolderList
* pUNOStorageHolderList
= pStg
->GetUNOStorageHolderList();
771 if ( !pUNOStorageHolderList
)
774 for ( UNOStorageHolderList::iterator aIter
= pUNOStorageHolderList
->begin();
775 aIter
!= pUNOStorageHolderList
->end(); aIter
++ )
776 if ( (*aIter
) && (*aIter
)->GetStorageName().Equals( rEleName
) )
778 // the storage is already in use
782 if ( IsStream( rEleName
) )
785 if ( GetError() == ERRCODE_NONE
)
787 StreamMode nMode
= ( ( nUNOStorageMode
& embed::ElementModes::WRITE
) == embed::ElementModes::WRITE
) ?
788 STREAM_WRITE
: ( STREAM_READ
| STREAM_NOCREATE
);
789 if ( nUNOStorageMode
& embed::ElementModes::NOCREATE
)
790 nMode
|= STREAM_NOCREATE
;
792 sal_Bool bStorageReady
= !IsStorage( rEleName
);
793 SotStorageRef pChildStorage
= OpenUCBStorage( rEleName
, nMode
, STORAGE_TRANSACTED
);
794 if ( pChildStorage
->GetError() == ERRCODE_NONE
&& pChildStorage
->m_pOwnStg
)
796 ::utl::TempFile
* pTempFile
= new ::utl::TempFile();
797 if ( pTempFile
->GetURL().Len() )
799 if ( !bStorageReady
)
801 UCBStorage
* pChildUCBStg
= PTR_CAST( UCBStorage
, pChildStorage
->m_pOwnStg
);
804 UCBStorage
* pTempStorage
= new UCBStorage( pTempFile
->GetURL(), STREAM_WRITE
, FALSE
, TRUE
);
807 pChildUCBStg
->CopyTo( pTempStorage
);
809 // CopyTo does not transport unknown media type
810 // just workaround it
813 if ( pChildUCBStg
->GetProperty(
814 ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType
) )
815 pTempStorage
->SetProperty( ::rtl::OUString::createFromAscii( "MediaType" ), aMediaType
);
817 bStorageReady
= !pChildUCBStg
->GetError() && !pTempStorage
->GetError()
818 && pTempStorage
->Commit();
820 delete ((BaseStorage
*)pTempStorage
);
825 OSL_ENSURE( bStorageReady
, "Problem on storage copy!\n" );
831 uno::Reference
< lang::XSingleServiceFactory
> xStorageFactory(
832 ::comphelper::getProcessServiceFactory()->createInstance(
833 ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
836 OSL_ENSURE( xStorageFactory
.is(), "Can't create storage factory!\n" );
837 if ( xStorageFactory
.is() )
839 uno::Sequence
< uno::Any
> aArg( 2 );
840 aArg
[0] <<= ::rtl::OUString( pTempFile
->GetURL() );
841 aArg
[1] <<= nUNOStorageMode
;
842 uno::Reference
< embed::XStorage
> xDuplStorage(
843 xStorageFactory
->createInstanceWithArguments( aArg
),
846 OSL_ENSURE( xDuplStorage
.is(), "Can't open storage!\n" );
847 if ( xDuplStorage
.is() )
849 UNOStorageHolder
* pHolder
=
850 new UNOStorageHolder( *this, *pChildStorage
, xDuplStorage
, pTempFile
);
853 pUNOStorageHolderList
->push_back( pHolder
);
854 xResult
= xDuplStorage
;
858 catch( uno::Exception
& e
)
861 OSL_ENSURE( sal_False
, ::rtl::OUStringToOString( e
.Message
, RTL_TEXTENCODING_ASCII_US
) );
866 if ( pTempFile
!= NULL
)
870 SetError( pChildStorage
->GetError() );
876 /*************************************************************************
877 |* SotStorage::CreateMemoryStream()
880 *************************************************************************/
881 SvMemoryStream
* SotStorage::CreateMemoryStream()
883 SvMemoryStream
* pStm
= NULL
;
884 pStm
= new SvMemoryStream( 0x8000, 0x8000 );
885 SotStorageRef aStg
= new SotStorage( *pStm
);
890 aStg
.Clear(); // Storage vorher freigeben
897 /*************************************************************************
898 |* SotStorage::GetStorage()
901 *************************************************************************/
902 BOOL
SotStorage::IsStorageFile( const String
& rFileName
)
904 String
aName( rFileName
);
905 INetURLObject
aObj( aName
);
906 if ( aObj
.GetProtocol() == INET_PROT_NOT_VALID
)
909 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName
, aURL
);
911 aName
= aObj
.GetMainURL( INetURLObject::NO_DECODE
);
914 SvStream
* pStm
= ::utl::UcbStreamHelper::CreateStream( aName
, STREAM_STD_READ
);
915 BOOL bRet
= SotStorage::IsStorageFile( pStm
);
920 BOOL
SotStorage::IsStorageFile( SvStream
* pStream
)
922 /** code for new storages must come first! **/
925 long nPos
= pStream
->Tell();
926 BOOL bRet
= UCBStorage::IsStorageFile( pStream
);
928 bRet
= Storage::IsStorageFile( pStream
);
929 pStream
->Seek( nPos
);
935 /*************************************************************************
936 |* SotStorage::GetStorage()
939 *************************************************************************/
940 const String
& SotStorage::GetName() const
944 DBG_ASSERT( Owner(), "must be owner" );
946 ((SotStorage
*)this)->m_aName
= m_pOwnStg
->GetName();
951 void SotStorage::SetName( const String
& rName
)
953 // This method is necessary because most storages will not be opened with a FileName, but an external stream instead
954 // 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
955 // class that depends on the fact that a root storage has a name
956 DBG_ASSERT( !GetName().Len(), "SetName() must not be called when the storage already has a name!" );
960 /*************************************************************************
961 |* SotStorage::ResetError()
964 *************************************************************************/
965 void SotStorage::ResetError()
967 m_nError
= SVSTREAM_OK
;
969 m_pOwnStg
->ResetError();
972 /*************************************************************************
973 |* SotStorage::SetClass()
974 |* SotStorage::SetConvertClass()
977 *************************************************************************/
978 void SotStorage::SetClass( const SvGlobalName
& rName
,
979 ULONG nOriginalClipFormat
,
980 const String
& rUserTypeName
)
982 DBG_ASSERT( Owner(), "must be owner" );
984 m_pOwnStg
->SetClass( rName
, nOriginalClipFormat
, rUserTypeName
);
986 SetError( SVSTREAM_GENERALERROR
);
989 void SotStorage::SetConvertClass( const SvGlobalName
& rName
,
990 ULONG nOriginalClipFormat
,
991 const String
& rUserTypeName
)
993 DBG_ASSERT( Owner(), "must be owner" );
995 m_pOwnStg
->SetConvertClass( rName
, nOriginalClipFormat
, rUserTypeName
);
997 SetError( SVSTREAM_GENERALERROR
);
1000 /*************************************************************************
1001 |* SotStorage::GetClassName()
1002 |* SotStorage::GetFormat()
1003 |* SotStorage::GetUserName()
1004 |* SotStorage::ShouldConvert()
1007 *************************************************************************/
1008 SvGlobalName
SotStorage::GetClassName()
1011 DBG_ASSERT( Owner(), "must be owner" );
1013 aGN
= m_pOwnStg
->GetClassName();
1015 SetError( SVSTREAM_GENERALERROR
);
1019 ULONG
SotStorage::GetFormat()
1022 DBG_ASSERT( Owner(), "must be owner" );
1024 nFormat
= m_pOwnStg
->GetFormat();
1026 SetError( SVSTREAM_GENERALERROR
);
1030 String
SotStorage::GetUserName()
1033 DBG_ASSERT( Owner(), "must be owner" );
1035 aName
= m_pOwnStg
->GetUserName();
1037 SetError( SVSTREAM_GENERALERROR
);
1041 BOOL
SotStorage::ShouldConvert()
1043 DBG_ASSERT( Owner(), "must be owner" );
1045 return m_pOwnStg
->ShouldConvert();
1047 SetError( SVSTREAM_GENERALERROR
);
1051 /*************************************************************************
1052 |* SotStorage::FillInfoList()
1055 *************************************************************************/
1056 void SotStorage::FillInfoList( SvStorageInfoList
* pFillList
) const
1058 DBG_ASSERT( Owner(), "must be owner" );
1060 m_pOwnStg
->FillInfoList( pFillList
);
1063 /*************************************************************************
1064 |* SotStorage::CopyTo()
1067 *************************************************************************/
1068 BOOL
SotStorage::CopyTo( SotStorage
* pDestStg
)
1070 DBG_ASSERT( Owner(), "must be owner" );
1071 DBG_ASSERT( pDestStg
->Owner(), "must be owner" );
1072 if( m_pOwnStg
&& pDestStg
->m_pOwnStg
)
1074 m_pOwnStg
->CopyTo( pDestStg
->m_pOwnStg
);
1075 SetError( m_pOwnStg
->GetError() );
1076 pDestStg
->m_aKey
= m_aKey
;
1077 pDestStg
->m_nVersion
= m_nVersion
;
1080 SetError( SVSTREAM_GENERALERROR
);
1081 return SVSTREAM_OK
== GetError();
1084 /*************************************************************************
1085 |* SotStorage::Commit()
1088 *************************************************************************/
1089 BOOL
SotStorage::Commit()
1091 DBG_ASSERT( Owner(), "must be owner" );
1094 if( !m_pOwnStg
->Commit() )
1095 SetError( m_pOwnStg
->GetError() );
1098 SetError( SVSTREAM_GENERALERROR
);
1099 return SVSTREAM_OK
== GetError();
1102 /*************************************************************************
1103 |* SotStorage::Revert()
1106 *************************************************************************/
1107 BOOL
SotStorage::Revert()
1109 DBG_ASSERT( Owner(), "must be owner" );
1112 if( !m_pOwnStg
->Revert() )
1113 SetError( m_pOwnStg
->GetError() );
1116 SetError( SVSTREAM_GENERALERROR
);
1117 return SVSTREAM_OK
== GetError();
1120 /*************************************************************************
1121 |* SotStorage::OpenStream()
1124 *************************************************************************/
1125 SotStorageStream
* SotStorage::OpenEncryptedSotStream( const String
& rEleName
, const ByteString
& rKey
,
1127 StorageMode nStorageMode
)
1129 DBG_ASSERT( !nStorageMode
, "StorageModes ignored" );
1130 SotStorageStream
* pStm
= NULL
;
1131 DBG_ASSERT( Owner(), "must be owner" );
1134 // volle Ole-Patches einschalten
1135 // egal was kommt, nur exclusiv gestattet
1136 nMode
|= STREAM_SHARE_DENYALL
;
1137 ErrCode nE
= m_pOwnStg
->GetError();
1138 BaseStorageStream
* p
= m_pOwnStg
->OpenStream( rEleName
, nMode
,
1139 (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
, &rKey
);
1140 pStm
= new SotStorageStream( p
);
1143 m_pOwnStg
->ResetError(); // kein Fehler setzen
1144 if( nMode
& STREAM_TRUNC
)
1148 SetError( SVSTREAM_GENERALERROR
);
1152 SotStorageStream
* SotStorage::OpenSotStream( const String
& rEleName
,
1154 StorageMode nStorageMode
)
1156 DBG_ASSERT( !nStorageMode
, "StorageModes ignored" );
1157 SotStorageStream
* pStm
= NULL
;
1158 DBG_ASSERT( Owner(), "must be owner" );
1161 // volle Ole-Patches einschalten
1162 // egal was kommt, nur exclusiv gestattet
1163 nMode
|= STREAM_SHARE_DENYALL
;
1164 ErrCode nE
= m_pOwnStg
->GetError();
1165 BaseStorageStream
* p
= m_pOwnStg
->OpenStream( rEleName
, nMode
,
1166 (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
1167 pStm
= new SotStorageStream( p
);
1170 m_pOwnStg
->ResetError(); // kein Fehler setzen
1171 if( nMode
& STREAM_TRUNC
)
1175 SetError( SVSTREAM_GENERALERROR
);
1179 /*************************************************************************
1180 |* SotStorage::OpenStorage()
1183 *************************************************************************/
1184 SotStorage
* SotStorage::OpenSotStorage( const String
& rEleName
,
1186 StorageMode nStorageMode
)
1188 SotStorage
* pStor
= NULL
;
1189 DBG_ASSERT( Owner(), "must be owner" );
1192 nMode
|= STREAM_SHARE_DENYALL
;
1193 ErrCode nE
= m_pOwnStg
->GetError();
1194 BaseStorage
* p
= m_pOwnStg
->OpenStorage( rEleName
, nMode
,
1195 (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
1198 pStor
= new SotStorage( p
);
1200 m_pOwnStg
->ResetError(); // kein Fehler setzen
1206 SetError( SVSTREAM_GENERALERROR
);
1211 SotStorage
* SotStorage::OpenUCBStorage( const String
& rEleName
,
1213 StorageMode nStorageMode
)
1215 SotStorage
* pStor
= NULL
;
1216 DBG_ASSERT( Owner(), "must be owner" );
1219 nMode
|= STREAM_SHARE_DENYALL
;
1220 ErrCode nE
= m_pOwnStg
->GetError();
1221 BaseStorage
* p
= m_pOwnStg
->OpenUCBStorage( rEleName
, nMode
,
1222 (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
1223 pStor
= new SotStorage( p
);
1225 m_pOwnStg
->ResetError(); // kein Fehler setzen
1228 SetError( SVSTREAM_GENERALERROR
);
1232 SotStorage
* SotStorage::OpenOLEStorage( const String
& rEleName
,
1234 StorageMode nStorageMode
)
1236 SotStorage
* pStor
= NULL
;
1237 DBG_ASSERT( Owner(), "must be owner" );
1240 nMode
|= STREAM_SHARE_DENYALL
;
1241 ErrCode nE
= m_pOwnStg
->GetError();
1242 BaseStorage
* p
= m_pOwnStg
->OpenOLEStorage( rEleName
, nMode
,
1243 (nStorageMode
& STORAGE_TRANSACTED
) ? FALSE
: TRUE
);
1244 pStor
= new SotStorage( p
);
1246 m_pOwnStg
->ResetError(); // kein Fehler setzen
1249 SetError( SVSTREAM_GENERALERROR
);
1253 /*************************************************************************
1254 |* SotStorage::IsStream()
1255 |* SotStorage::IsStorage()
1256 |* SotStorage::IsContained()
1259 *************************************************************************/
1260 BOOL
SotStorage::IsStorage( const String
& rEleName
) const
1262 DBG_ASSERT( Owner(), "must be owner" );
1263 // ein bisschen schneller
1265 return m_pOwnStg
->IsStorage( rEleName
);
1269 BOOL
SotStorage::IsStream( const String
& rEleName
) const
1271 DBG_ASSERT( Owner(), "must be owner" );
1272 // ein bisschen schneller
1274 return m_pOwnStg
->IsStream( rEleName
);
1278 BOOL
SotStorage::IsContained( const String
& rEleName
) const
1280 DBG_ASSERT( Owner(), "must be owner" );
1281 // ein bisschen schneller
1283 return m_pOwnStg
->IsContained( rEleName
);
1287 /*************************************************************************
1288 |* SotStorage::Remove()
1291 *************************************************************************/
1292 BOOL
SotStorage::Remove( const String
& rEleName
)
1294 DBG_ASSERT( Owner(), "must be owner" );
1297 m_pOwnStg
->Remove( rEleName
);
1298 SetError( m_pOwnStg
->GetError() );
1301 SetError( SVSTREAM_GENERALERROR
);
1302 return SVSTREAM_OK
== GetError();
1305 /*************************************************************************
1306 |* SotStorage::Rename()
1309 *************************************************************************/
1310 BOOL
SotStorage::Rename( const String
& rEleName
, const String
& rNewName
)
1312 DBG_ASSERT( Owner(), "must be owner" );
1315 m_pOwnStg
->Rename( rEleName
, rNewName
);
1316 SetError( m_pOwnStg
->GetError() );
1319 SetError( SVSTREAM_GENERALERROR
);
1320 return SVSTREAM_OK
== GetError();
1323 /*************************************************************************
1324 |* SotStorage::CopyTo()
1327 *************************************************************************/
1328 BOOL
SotStorage::CopyTo( const String
& rEleName
,
1329 SotStorage
* pNewSt
, const String
& rNewName
)
1331 DBG_ASSERT( Owner(), "must be owner" );
1332 DBG_ASSERT( pNewSt
->Owner(), "must be owner" );
1335 m_pOwnStg
->CopyTo( rEleName
, pNewSt
->m_pOwnStg
, rNewName
);
1336 SetError( m_pOwnStg
->GetError() );
1337 SetError( pNewSt
->GetError() );
1340 SetError( SVSTREAM_GENERALERROR
);
1341 return SVSTREAM_OK
== GetError();
1344 /*************************************************************************
1345 |* SotStorage::MoveTo()
1348 *************************************************************************/
1349 BOOL
SotStorage::MoveTo( const String
& rEleName
,
1350 SotStorage
* pNewSt
, const String
& rNewName
)
1352 DBG_ASSERT( Owner(), "must be owner" );
1353 DBG_ASSERT( pNewSt
->Owner(), "must be owner" );
1356 m_pOwnStg
->MoveTo( rEleName
, pNewSt
->m_pOwnStg
, rNewName
);
1357 SetError( m_pOwnStg
->GetError() );
1358 SetError( pNewSt
->GetError() );
1361 SetError( SVSTREAM_GENERALERROR
);
1362 return SVSTREAM_OK
== GetError();
1365 const SvStream
* SotStorage::GetSvStream()
1367 const SvStream
* pResult
= 0;
1368 DBG_ASSERT( Owner(), "must be owner" );
1370 pResult
= m_pOwnStg
->GetSvStream();
1374 SvStream
* SotStorage::GetTargetSvStream() const
1376 SvStream
* pResult
= 0;
1377 DBG_ASSERT( Owner(), "must be owner" );
1379 pResult
= (SvStream
*)(m_pOwnStg
->GetSvStream());
1384 BOOL
SotStorage::Validate()
1386 DBG_ASSERT( m_bIsRoot
, "Validate nur an Rootstorage" );
1388 return m_pOwnStg
->ValidateFAT();
1393 BOOL
SotStorage::SetProperty( const String
& rName
, const ::com::sun::star::uno::Any
& rValue
)
1395 UCBStorage
* pStg
= PTR_CAST( UCBStorage
, m_pOwnStg
);
1398 return pStg
->SetProperty( rName
, rValue
);
1402 DBG_WARNING("W1:Not implemented!");
1407 BOOL
SotStorage::GetProperty( const String
& rName
, ::com::sun::star::uno::Any
& rValue
)
1409 UCBStorage
* pStg
= PTR_CAST( UCBStorage
, m_pOwnStg
);
1412 return pStg
->GetProperty( rName
, rValue
);
1414 else if ( rName
.CompareToAscii("MediaType") == COMPARE_EQUAL
)
1416 String aStr
= SotExchange::GetFormatMimeType( GetFormat() );
1417 USHORT nPos
= aStr
.Search(';');
1418 if ( nPos
!= STRING_NOTFOUND
)
1419 aStr
= aStr
.Copy( 0, nPos
);
1420 rValue
<<= (::rtl::OUString
) aStr
;
1425 DBG_WARNING("W1:Not implemented!");
1430 BOOL
SotStorage::GetProperty( const String
& rEleName
, const String
& rName
, ::com::sun::star::uno::Any
& rValue
)
1432 UCBStorage
* pStg
= PTR_CAST( UCBStorage
, m_pOwnStg
);
1435 return pStg
->GetProperty( rEleName
, rName
, rValue
);
1439 DBG_WARNING("W1:Not implemented!");
1444 BOOL
SotStorage::IsOLEStorage() const
1446 UCBStorage
* pStg
= PTR_CAST( UCBStorage
, m_pOwnStg
);
1450 BOOL
SotStorage::IsOLEStorage( const String
& rFileName
)
1452 return Storage::IsStorageFile( rFileName
);
1455 BOOL
SotStorage::IsOLEStorage( SvStream
* pStream
)
1457 return Storage::IsStorageFile( pStream
);
1460 void SotStorage::SetKey( const ByteString
& rKey
)
1463 if ( !IsOLEStorage() )
1465 sal_uInt8 aBuffer
[RTL_DIGEST_LENGTH_SHA1
];
1466 rtlDigestError nError
= rtl_digest_SHA1( m_aKey
.GetBuffer(), m_aKey
.Len(), aBuffer
, RTL_DIGEST_LENGTH_SHA1
);
1467 if ( nError
== rtl_Digest_E_None
)
1469 sal_uInt8
* pBuffer
= aBuffer
;
1470 ::com::sun::star::uno::Sequence
< sal_Int8
> aSequ( (sal_Int8
*) pBuffer
, RTL_DIGEST_LENGTH_SHA1
);
1471 ::com::sun::star::uno::Any aAny
;
1473 SetProperty( ::rtl::OUString::createFromAscii("EncryptionKey"), aAny
);
1478 SotStorage
* SotStorage::OpenOLEStorage( const com::sun::star::uno::Reference
< com::sun::star::embed::XStorage
>& xStorage
,
1479 const String
& rEleName
, StreamMode nMode
)
1481 sal_Int32 nEleMode
= embed::ElementModes::SEEKABLEREAD
;
1482 if ( nMode
& STREAM_WRITE
)
1483 nEleMode
|= embed::ElementModes::WRITE
;
1484 if ( nMode
& STREAM_TRUNC
)
1485 nEleMode
|= embed::ElementModes::TRUNCATE
;
1486 if ( nMode
& STREAM_NOCREATE
)
1487 nEleMode
|= embed::ElementModes::NOCREATE
;
1489 SvStream
* pStream
= NULL
;
1492 uno::Reference
< io::XStream
> xStream
= xStorage
->openStreamElement( rEleName
, nEleMode
);
1494 // TODO/LATER: should it be done this way?
1495 if ( nMode
& STREAM_WRITE
)
1497 uno::Reference
< beans::XPropertySet
> xStreamProps( xStream
, uno::UNO_QUERY_THROW
);
1498 xStreamProps
->setPropertyValue(
1499 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1500 uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) );
1503 pStream
= utl::UcbStreamHelper::CreateStream( xStream
);
1505 catch ( uno::Exception
& )
1507 //TODO/LATER: ErrorHandling
1508 pStream
= new SvMemoryStream
;
1509 pStream
->SetError( ERRCODE_IO_GENERAL
);
1512 return new SotStorage( pStream
, TRUE
);
1515 sal_Int32
SotStorage::GetFormatID( const com::sun::star::uno::Reference
< com::sun::star::embed::XStorage
>& xStorage
)
1517 uno::Reference
< beans::XPropertySet
> xProps( xStorage
, uno::UNO_QUERY
);
1521 ::rtl::OUString aMediaType
;
1522 xProps
->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType
;
1523 if ( aMediaType
.getLength() )
1525 ::com::sun::star::datatransfer::DataFlavor aDataFlavor
;
1526 aDataFlavor
.MimeType
= aMediaType
;
1527 return SotExchange::GetFormat( aDataFlavor
);
1533 sal_Int32
SotStorage::GetVersion( const com::sun::star::uno::Reference
< com::sun::star::embed::XStorage
>& xStorage
)
1535 sal_Int32 nSotFormatID
= SotStorage::GetFormatID( xStorage
);
1536 switch( nSotFormatID
)
1538 case SOT_FORMATSTR_ID_STARWRITER_8
:
1539 case SOT_FORMATSTR_ID_STARWRITER_8_TEMPLATE
:
1540 case SOT_FORMATSTR_ID_STARWRITERWEB_8
:
1541 case SOT_FORMATSTR_ID_STARWRITERGLOB_8
:
1542 case SOT_FORMATSTR_ID_STARDRAW_8
:
1543 case SOT_FORMATSTR_ID_STARDRAW_8_TEMPLATE
:
1544 case SOT_FORMATSTR_ID_STARIMPRESS_8
:
1545 case SOT_FORMATSTR_ID_STARIMPRESS_8_TEMPLATE
:
1546 case SOT_FORMATSTR_ID_STARCALC_8
:
1547 case SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE
:
1548 case SOT_FORMATSTR_ID_STARCHART_8
:
1549 case SOT_FORMATSTR_ID_STARCHART_8_TEMPLATE
:
1550 case SOT_FORMATSTR_ID_STARMATH_8
:
1551 case SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE
:
1552 return SOFFICE_FILEFORMAT_8
;
1553 case SOT_FORMATSTR_ID_STARWRITER_60
:
1554 case SOT_FORMATSTR_ID_STARWRITERWEB_60
:
1555 case SOT_FORMATSTR_ID_STARWRITERGLOB_60
:
1556 case SOT_FORMATSTR_ID_STARDRAW_60
:
1557 case SOT_FORMATSTR_ID_STARIMPRESS_60
:
1558 case SOT_FORMATSTR_ID_STARCALC_60
:
1559 case SOT_FORMATSTR_ID_STARCHART_60
:
1560 case SOT_FORMATSTR_ID_STARMATH_60
:
1561 return SOFFICE_FILEFORMAT_60
;