bump product version to 4.2.0.1
[LibreOffice.git] / sot / source / sdstor / storage.cxx
blob3ae0236685338e093d3f37bfd61ba57b50539c06
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/uno/Sequence.hxx>
21 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
22 #include <com/sun/star/embed/XStorage.hpp>
23 #include <com/sun/star/embed/ElementModes.hpp>
24 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <rtl/digest.h>
27 #include <osl/file.hxx>
28 #include <sot/stg.hxx>
29 #include <sot/storinfo.hxx>
30 #include <sot/storage.hxx>
31 #include <sot/formats.hxx>
32 #include <sot/exchange.hxx>
33 #include <unotools/ucbstreamhelper.hxx>
34 #include <tools/debug.hxx>
35 #include <tools/urlobj.hxx>
36 #include <unotools/localfilehelper.hxx>
37 #include <unotools/ucbhelper.hxx>
38 #include <comphelper/processfactory.hxx>
40 using namespace ::com::sun::star;
42 /************** class SotStorageStream ***********************************/
43 class SotStorageStreamFactory : public SotFactory
45 public:
46 TYPEINFO();
47 SotStorageStreamFactory( const SvGlobalName & rName,
48 const OUString & rClassName,
49 CreateInstanceType pCreateFuncP )
50 : SotFactory( rName, rClassName, pCreateFuncP )
53 TYPEINIT1(SotStorageStreamFactory,SotFactory);
56 SO2_IMPL_BASIC_CLASS1_DLL(SotStorageStream,SotStorageStreamFactory,SotObject,
57 SvGlobalName( 0xd7deb420, 0xf902, 0x11d0,
58 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
60 SvLockBytesRef MakeLockBytes_Impl( const OUString & rName, StreamMode nMode )
62 SvLockBytesRef xLB;
63 if( !rName.isEmpty() )
65 SvStream * pFileStm = new SvFileStream( rName, nMode );
66 xLB = new SvLockBytes( pFileStm, true );
68 else
70 SvStream * pCacheStm = new SvMemoryStream();
71 xLB = new SvLockBytes( pCacheStm, true );
73 return xLB;
76 SotStorageStream::SotStorageStream( const OUString & rName, StreamMode nMode,
77 StorageMode
78 #ifdef DBG_UTIL
79 nStorageMode
80 #endif
82 : SvStream( MakeLockBytes_Impl( rName, nMode ) )
83 , pOwnStm( NULL )
85 if( nMode & STREAM_WRITE )
86 bIsWritable = true;
87 else
88 bIsWritable = false;
90 DBG_ASSERT( !nStorageMode,"StorageModes ignored" );
93 SotStorageStream::SotStorageStream( BaseStorageStream * pStm )
95 if( pStm )
97 if( STREAM_WRITE & pStm->GetMode() )
98 bIsWritable = true;
99 else
100 bIsWritable = false;
102 pOwnStm = pStm;
103 SetError( pStm->GetError() );
104 pStm->ResetError();
106 else
108 pOwnStm = NULL;
109 bIsWritable = true;
110 SetError( SVSTREAM_INVALID_PARAMETER );
114 SotStorageStream::SotStorageStream()
115 : pOwnStm( NULL )
117 // ??? wenn Init virtuell ist, entsprechen setzen
118 bIsWritable = true;
121 SotStorageStream::~SotStorageStream()
123 Flush(); //SetBufferSize(0);
124 delete pOwnStm;
127 void SotStorageStream::ResetError()
129 SvStream::ResetError();
130 if( pOwnStm )
131 pOwnStm->ResetError();
134 sal_uLong SotStorageStream::GetData( void* pData, sal_uLong nSize )
136 sal_uLong nRet = 0;
138 if( pOwnStm )
140 nRet = pOwnStm->Read( pData, nSize );
141 SetError( pOwnStm->GetError() );
143 else
144 nRet = SvStream::GetData( (sal_Char *)pData, nSize );
146 return nRet;
149 sal_uLong SotStorageStream::PutData( const void* pData, sal_uLong nSize )
151 sal_uLong nRet = 0;
153 if( pOwnStm )
155 nRet = pOwnStm->Write( pData, nSize );
156 SetError( pOwnStm->GetError() );
158 else
159 nRet = SvStream::PutData( (sal_Char *)pData, nSize );
160 return nRet;
163 sal_uLong SotStorageStream::SeekPos( sal_uLong nPos )
165 sal_uLong nRet = 0;
167 if( pOwnStm )
169 nRet = pOwnStm->Seek( nPos );
170 SetError( pOwnStm->GetError() );
172 else
173 nRet = SvStream::SeekPos( nPos );
175 return nRet;
178 void SotStorageStream::FlushData()
180 if( pOwnStm )
182 pOwnStm->Flush();
183 SetError( pOwnStm->GetError() );
185 else
186 SvStream::FlushData();
189 void SotStorageStream::SetSize( sal_uLong nNewSize )
191 sal_uLong nPos = Tell();
192 if( pOwnStm )
194 pOwnStm->SetSize( nNewSize );
195 SetError( pOwnStm->GetError() );
197 else
198 SvStream::SetSize( nNewSize );
200 if( nNewSize < nPos )
201 // ans Ende setzen
202 Seek( nNewSize );
205 sal_uInt32 SotStorageStream::GetSize() const
207 sal_uLong nPos = Tell();
208 ((SotStorageStream *)this)->Seek( STREAM_SEEK_TO_END );
209 sal_uLong nSize = Tell();
210 ((SotStorageStream *)this)->Seek( nPos );
211 return nSize;
214 sal_Size SotStorageStream::remainingSize()
216 if (pOwnStm)
217 return pOwnStm->GetSize() - Tell();
219 return SvStream::remainingSize();
222 bool SotStorageStream::CopyTo( SotStorageStream * pDestStm )
224 Flush(); // alle Daten schreiben
225 pDestStm->ClearBuffer();
226 if( !pOwnStm || !pDestStm->pOwnStm )
228 // Wenn Ole2 oder nicht nur eigene StorageStreams
229 sal_uLong nPos = Tell(); // Position merken
230 Seek( 0L );
231 pDestStm->SetSize( 0 ); // Ziel-Stream leeren
233 void * pMem = new sal_uInt8[ 8192 ];
234 sal_uLong nRead;
235 while( 0 != (nRead = Read( pMem, 8192 )) )
237 if( nRead != pDestStm->Write( pMem, nRead ) )
239 SetError( SVSTREAM_GENERALERROR );
240 break;
243 delete [] static_cast<sal_uInt8*>(pMem);
244 // Position setzen
245 pDestStm->Seek( nPos );
246 Seek( nPos );
248 else
250 pOwnStm->CopyTo( pDestStm->pOwnStm );
251 SetError( pOwnStm->GetError() );
253 return GetError() == SVSTREAM_OK;
256 bool SotStorageStream::Commit()
258 if( pOwnStm )
260 pOwnStm->Flush();
261 if( pOwnStm->GetError() == SVSTREAM_OK )
262 pOwnStm->Commit();
263 SetError( pOwnStm->GetError() );
265 return GetError() == SVSTREAM_OK;
268 bool SotStorageStream::Revert()
270 if( pOwnStm )
272 pOwnStm->Revert();
273 SetError( pOwnStm->GetError() );
275 return GetError() == SVSTREAM_OK;
278 bool SotStorageStream::SetProperty( const OUString& rName, const ::com::sun::star::uno::Any& rValue )
280 UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pOwnStm );
281 if ( pStg )
283 return pStg->SetProperty( rName, rValue );
285 else
287 OSL_FAIL("Not implemented!");
288 return false;
292 /************** class SotStorage ******************************************
293 *************************************************************************/
294 class SotStorageFactory : public SotFactory
296 public:
297 TYPEINFO();
298 SotStorageFactory( const SvGlobalName & rName,
299 const OUString & rClassName,
300 CreateInstanceType pCreateFuncP )
301 : SotFactory( rName, rClassName, pCreateFuncP )
304 TYPEINIT1(SotStorageFactory,SotFactory);
307 SO2_IMPL_BASIC_CLASS1_DLL(SotStorage,SotStorageFactory,SotObject,
308 SvGlobalName( 0x980ce7e0, 0xf905, 0x11d0,
309 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
311 /************************************************************************
313 |* SotStorage::SotStorage()
315 |* Beschreibung Es muss ein I... Objekt an SvObject uebergeben
316 |* werden, da es sonst selbst ein IUnknown anlegt und
317 |* festlegt, dass alle weiteren I... Objekte mit
318 |* delete zerstoert werden (Owner() == true).
319 |* Es werden aber nur IStorage Objekte benutzt und nicht
320 |* selbst implementiert, deshalb wird so getan, als ob
321 |* das IStorage Objekt von aussen kam und es wird mit
322 |* Release() freigegeben.
323 |* Die CreateStorage Methoden werden benoetigt, um
324 |* ein IStorage Objekt vor dem Aufruf von SvObject
325 |* zu erzeugen (Own, !Own automatik).
326 |* Hat CreateStorage ein Objekt erzeugt, dann wurde
327 |* der RefCounter schon um 1 erhoet.
328 |* Die Uebergabe erfolgt in pStorageCTor. Die Variable
329 |* ist NULL, wenn es nicht geklappt hat.
331 *************************************************************************/
332 #define INIT_SotStorage() \
333 : m_pOwnStg( NULL ) \
334 , m_pStorStm( NULL ) \
335 , m_nError( SVSTREAM_OK ) \
336 , m_bIsRoot( false ) \
337 , m_bDelStm( false ) \
338 , m_nVersion( SOFFICE_FILEFORMAT_CURRENT )
340 SotStorage::SotStorage()
341 INIT_SotStorage()
343 // ??? What's this ???
346 #define ERASEMASK ( STREAM_TRUNC | STREAM_WRITE | STREAM_SHARE_DENYALL )
347 #include <com/sun/star/uno/Reference.h>
348 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
349 #include <ucbhelper/content.hxx>
351 SotStorage::SotStorage( const OUString & rName, StreamMode nMode, StorageMode nStorageMode )
352 INIT_SotStorage()
354 m_aName = rName; // Namen merken
355 CreateStorage( true, nMode, nStorageMode );
356 if ( IsOLEStorage() )
357 m_nVersion = SOFFICE_FILEFORMAT_50;
360 void SotStorage::CreateStorage( bool bForceUCBStorage, StreamMode nMode, StorageMode nStorageMode )
362 DBG_ASSERT( !m_pStorStm && !m_pOwnStg, "Use only in ctor!" );
363 if( !m_aName.isEmpty() )
365 // named storage
366 if( ( ( nMode & ERASEMASK ) == ERASEMASK ) )
367 ::utl::UCBContentHelper::Kill( m_aName );
369 INetURLObject aObj( m_aName );
370 if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
372 OUString aURL;
373 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( m_aName, aURL );
374 aObj.SetURL( aURL );
375 m_aName = aObj.GetMainURL( INetURLObject::NO_DECODE );
378 // a new unpacked storage should be created
379 if ( nStorageMode == STORAGE_CREATE_UNPACKED )
381 // don't open stream readwrite, content provider may not support this !
382 OUString aURL = UCBStorage::CreateLinkFile( m_aName );
383 if ( !aURL.isEmpty() )
385 ::ucbhelper::Content aContent( aURL, ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
386 m_pOwnStg = new UCBStorage( aContent, aURL, nMode, false );
388 else
390 m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
391 SetError( ERRCODE_IO_NOTSUPPORTED );
394 else
396 // check the stream
397 m_pStorStm = ::utl::UcbStreamHelper::CreateStream( m_aName, nMode );
398 if ( m_pStorStm && m_pStorStm->GetError() )
399 DELETEZ( m_pStorStm );
401 if ( m_pStorStm )
403 // try as UCBStorage, next try as OLEStorage
404 bool bIsUCBStorage = UCBStorage::IsStorageFile( m_pStorStm );
405 if ( !bIsUCBStorage && bForceUCBStorage )
406 // if UCBStorage has priority, it should not be used only if it is really an OLEStorage
407 bIsUCBStorage = !Storage::IsStorageFile( m_pStorStm );
409 if ( bIsUCBStorage )
411 if ( !(UCBStorage::GetLinkedFile( *m_pStorStm ).isEmpty()) )
413 // detect special unpacked storages
414 m_pOwnStg = new UCBStorage( *m_pStorStm, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
415 m_bDelStm = true;
417 else
419 // detect special disk spanned storages
420 if ( UCBStorage::IsDiskSpannedFile( m_pStorStm ) )
421 nMode |= STORAGE_DISKSPANNED_MODE;
423 // UCBStorage always works directly on the UCB content, so discard the stream first
424 DELETEZ( m_pStorStm );
425 m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
428 else
430 // OLEStorage can be opened with a stream
431 m_pOwnStg = new Storage( *m_pStorStm, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
432 m_bDelStm = true;
435 else if ( bForceUCBStorage )
437 m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
438 SetError( ERRCODE_IO_NOTSUPPORTED );
440 else
442 m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
443 SetError( ERRCODE_IO_NOTSUPPORTED );
447 else
449 // temporary storage
450 if ( bForceUCBStorage )
451 m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
452 else
453 m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
454 m_aName = m_pOwnStg->GetName();
457 SetError( m_pOwnStg->GetError() );
459 SignAsRoot( m_pOwnStg->IsRoot() );
462 SotStorage::SotStorage( bool bUCBStorage, const OUString & rName, StreamMode nMode, StorageMode nStorageMode )
463 INIT_SotStorage()
465 m_aName = rName;
466 CreateStorage( bUCBStorage, nMode, nStorageMode );
467 if ( IsOLEStorage() )
468 m_nVersion = SOFFICE_FILEFORMAT_50;
471 SotStorage::SotStorage( BaseStorage * pStor )
472 INIT_SotStorage()
474 if ( pStor )
476 m_aName = pStor->GetName(); // Namen merken
477 SignAsRoot( pStor->IsRoot() );
478 SetError( pStor->GetError() );
481 m_pOwnStg = pStor;
482 sal_uLong nErr = m_pOwnStg ? m_pOwnStg->GetError() : SVSTREAM_CANNOT_MAKE;
483 SetError( nErr );
484 if ( IsOLEStorage() )
485 m_nVersion = SOFFICE_FILEFORMAT_50;
488 SotStorage::SotStorage( bool bUCBStorage, SvStream & rStm )
489 INIT_SotStorage()
491 SetError( rStm.GetError() );
493 // try as UCBStorage, next try as OLEStorage
494 if ( UCBStorage::IsStorageFile( &rStm ) || bUCBStorage )
495 m_pOwnStg = new UCBStorage( rStm, false );
496 else
497 m_pOwnStg = new Storage( rStm, false );
499 SetError( m_pOwnStg->GetError() );
501 if ( IsOLEStorage() )
502 m_nVersion = SOFFICE_FILEFORMAT_50;
504 SignAsRoot( m_pOwnStg->IsRoot() );
507 SotStorage::SotStorage( SvStream & rStm )
508 INIT_SotStorage()
510 SetError( rStm.GetError() );
512 // try as UCBStorage, next try as OLEStorage
513 if ( UCBStorage::IsStorageFile( &rStm ) )
514 m_pOwnStg = new UCBStorage( rStm, false );
515 else
516 m_pOwnStg = new Storage( rStm, false );
518 SetError( m_pOwnStg->GetError() );
520 if ( IsOLEStorage() )
521 m_nVersion = SOFFICE_FILEFORMAT_50;
523 SignAsRoot( m_pOwnStg->IsRoot() );
526 SotStorage::SotStorage( SvStream * pStm, bool bDelete )
527 INIT_SotStorage()
529 SetError( pStm->GetError() );
531 // try as UCBStorage, next try as OLEStorage
532 if ( UCBStorage::IsStorageFile( pStm ) )
533 m_pOwnStg = new UCBStorage( *pStm, false );
534 else
535 m_pOwnStg = new Storage( *pStm, false );
537 SetError( m_pOwnStg->GetError() );
539 m_pStorStm = pStm;
540 m_bDelStm = bDelete;
541 if ( IsOLEStorage() )
542 m_nVersion = SOFFICE_FILEFORMAT_50;
544 SignAsRoot( m_pOwnStg->IsRoot() );
547 SotStorage::~SotStorage()
549 delete m_pOwnStg;
550 if( m_bDelStm )
551 delete m_pStorStm;
554 SvMemoryStream * SotStorage::CreateMemoryStream()
556 SvMemoryStream * pStm = NULL;
557 pStm = new SvMemoryStream( 0x8000, 0x8000 );
558 SotStorageRef aStg = new SotStorage( *pStm );
559 if( CopyTo( aStg ) )
561 aStg->Commit();
563 else
565 aStg.Clear(); // Storage vorher freigeben
566 delete pStm;
567 pStm = NULL;
569 return pStm;
572 bool SotStorage::IsStorageFile( const OUString & rFileName )
574 OUString aName( rFileName );
575 INetURLObject aObj( aName );
576 if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
578 OUString aURL;
579 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL );
580 aObj.SetURL( aURL );
581 aName = aObj.GetMainURL( INetURLObject::NO_DECODE );
584 SvStream * pStm = ::utl::UcbStreamHelper::CreateStream( aName, STREAM_STD_READ );
585 bool bRet = SotStorage::IsStorageFile( pStm );
586 delete pStm;
587 return bRet;
590 bool SotStorage::IsStorageFile( SvStream* pStream )
592 /** code for new storages must come first! **/
593 if ( pStream )
595 long nPos = pStream->Tell();
596 bool bRet = UCBStorage::IsStorageFile( pStream );
597 if ( !bRet )
598 bRet = Storage::IsStorageFile( pStream );
599 pStream->Seek( nPos );
600 return bRet;
602 else
603 return false;
606 const OUString & SotStorage::GetName() const
608 if( m_aName.isEmpty() )
610 DBG_ASSERT( Owner(), "must be owner" );
611 if( m_pOwnStg )
612 ((SotStorage *)this)->m_aName = m_pOwnStg->GetName();
614 return m_aName;
617 const OString& SotStorage::GetKey() const
619 return m_aKey;
622 void SotStorage::ResetError()
624 m_nError = SVSTREAM_OK;
625 if( m_pOwnStg )
626 m_pOwnStg->ResetError();
629 void SotStorage::SetClass( const SvGlobalName & rName,
630 sal_uLong nOriginalClipFormat,
631 const OUString & rUserTypeName )
633 DBG_ASSERT( Owner(), "must be owner" );
634 if( m_pOwnStg )
635 m_pOwnStg->SetClass( rName, nOriginalClipFormat, rUserTypeName );
636 else
637 SetError( SVSTREAM_GENERALERROR );
640 void SotStorage::SetConvertClass( const SvGlobalName & rName,
641 sal_uLong nOriginalClipFormat,
642 const OUString & rUserTypeName )
644 DBG_ASSERT( Owner(), "must be owner" );
645 if( m_pOwnStg )
646 m_pOwnStg->SetConvertClass( rName, nOriginalClipFormat, rUserTypeName );
647 else
648 SetError( SVSTREAM_GENERALERROR );
651 SvGlobalName SotStorage::GetClassName()
653 SvGlobalName aGN;
654 DBG_ASSERT( Owner(), "must be owner" );
655 if( m_pOwnStg )
656 aGN = m_pOwnStg->GetClassName();
657 else
658 SetError( SVSTREAM_GENERALERROR );
659 return aGN;
662 sal_uLong SotStorage::GetFormat()
664 sal_uLong nFormat = 0;
665 DBG_ASSERT( Owner(), "must be owner" );
666 if( m_pOwnStg )
667 nFormat = m_pOwnStg->GetFormat();
668 else
669 SetError( SVSTREAM_GENERALERROR );
670 return nFormat;
673 OUString SotStorage::GetUserName()
675 OUString aName;
676 DBG_ASSERT( Owner(), "must be owner" );
677 if( m_pOwnStg )
678 aName = m_pOwnStg->GetUserName();
679 else
680 SetError( SVSTREAM_GENERALERROR );
681 return aName;
684 bool SotStorage::ShouldConvert()
686 DBG_ASSERT( Owner(), "must be owner" );
687 if( m_pOwnStg )
688 return m_pOwnStg->ShouldConvert();
689 else
690 SetError( SVSTREAM_GENERALERROR );
691 return false;
694 void SotStorage::FillInfoList( SvStorageInfoList * pFillList ) const
696 DBG_ASSERT( Owner(), "must be owner" );
697 if( m_pOwnStg )
698 m_pOwnStg->FillInfoList( pFillList );
701 bool SotStorage::CopyTo( SotStorage * pDestStg )
703 DBG_ASSERT( Owner(), "must be owner" );
704 DBG_ASSERT( pDestStg->Owner(), "must be owner" );
705 if( m_pOwnStg && pDestStg->m_pOwnStg )
707 m_pOwnStg->CopyTo( pDestStg->m_pOwnStg );
708 SetError( m_pOwnStg->GetError() );
709 pDestStg->m_aKey = m_aKey;
710 pDestStg->m_nVersion = m_nVersion;
712 else
713 SetError( SVSTREAM_GENERALERROR );
715 return SVSTREAM_OK == GetError();
718 bool SotStorage::Commit()
720 DBG_ASSERT( Owner(), "must be owner" );
721 if( m_pOwnStg )
723 if( !m_pOwnStg->Commit() )
724 SetError( m_pOwnStg->GetError() );
726 else
727 SetError( SVSTREAM_GENERALERROR );
729 return SVSTREAM_OK == GetError();
732 bool SotStorage::Revert()
734 DBG_ASSERT( Owner(), "must be owner" );
735 if( m_pOwnStg )
737 if( !m_pOwnStg->Revert() )
738 SetError( m_pOwnStg->GetError() );
740 else
741 SetError( SVSTREAM_GENERALERROR );
743 return SVSTREAM_OK == GetError();
746 SotStorageStream * SotStorage::OpenSotStream( const OUString & rEleName,
747 StreamMode nMode,
748 StorageMode nStorageMode )
750 DBG_ASSERT( !nStorageMode, "StorageModes ignored" );
751 SotStorageStream * pStm = NULL;
752 DBG_ASSERT( Owner(), "must be owner" );
753 if( m_pOwnStg )
755 // volle Ole-Patches einschalten
756 // egal was kommt, nur exclusiv gestattet
757 nMode |= STREAM_SHARE_DENYALL;
758 ErrCode nE = m_pOwnStg->GetError();
759 BaseStorageStream * p = m_pOwnStg->OpenStream( rEleName, nMode,
760 (nStorageMode & STORAGE_TRANSACTED) ? false : true );
761 pStm = new SotStorageStream( p );
763 if( !nE )
764 m_pOwnStg->ResetError(); // kein Fehler setzen
765 if( nMode & STREAM_TRUNC )
766 pStm->SetSize( 0 );
768 else
769 SetError( SVSTREAM_GENERALERROR );
771 return pStm;
774 SotStorage * SotStorage::OpenSotStorage( const OUString & rEleName,
775 StreamMode nMode,
776 StorageMode nStorageMode )
778 SotStorage * pStor = NULL;
779 DBG_ASSERT( Owner(), "must be owner" );
780 if( m_pOwnStg )
782 nMode |= STREAM_SHARE_DENYALL;
783 ErrCode nE = m_pOwnStg->GetError();
784 BaseStorage * p = m_pOwnStg->OpenStorage( rEleName, nMode,
785 (nStorageMode & STORAGE_TRANSACTED) ? false : true );
786 if( p )
788 pStor = new SotStorage( p );
789 if( !nE )
790 m_pOwnStg->ResetError(); // kein Fehler setzen
792 return pStor;
796 SetError( SVSTREAM_GENERALERROR );
798 return NULL;
801 bool SotStorage::IsStorage( const OUString & rEleName ) const
803 DBG_ASSERT( Owner(), "must be owner" );
804 // ein bisschen schneller
805 if( m_pOwnStg )
806 return m_pOwnStg->IsStorage( rEleName );
808 return false;
811 bool SotStorage::IsStream( const OUString & rEleName ) const
813 DBG_ASSERT( Owner(), "must be owner" );
814 // ein bisschen schneller
815 if( m_pOwnStg )
816 return m_pOwnStg->IsStream( rEleName );
818 return false;
821 bool SotStorage::IsContained( const OUString & rEleName ) const
823 DBG_ASSERT( Owner(), "must be owner" );
824 // ein bisschen schneller
825 if( m_pOwnStg )
826 return m_pOwnStg->IsContained( rEleName );
828 return false;
831 bool SotStorage::Remove( const OUString & rEleName )
833 DBG_ASSERT( Owner(), "must be owner" );
834 if( m_pOwnStg )
836 m_pOwnStg->Remove( rEleName );
837 SetError( m_pOwnStg->GetError() );
839 else
840 SetError( SVSTREAM_GENERALERROR );
842 return SVSTREAM_OK == GetError();
845 bool SotStorage::Rename( const OUString & rEleName, const OUString & rNewName )
847 DBG_ASSERT( Owner(), "must be owner" );
848 if( m_pOwnStg )
850 m_pOwnStg->Rename( rEleName, rNewName );
851 SetError( m_pOwnStg->GetError() );
853 else
854 SetError( SVSTREAM_GENERALERROR );
856 return SVSTREAM_OK == GetError();
859 bool SotStorage::CopyTo( const OUString & rEleName,
860 SotStorage * pNewSt, const OUString & rNewName )
862 DBG_ASSERT( Owner(), "must be owner" );
863 DBG_ASSERT( pNewSt->Owner(), "must be owner" );
864 if( m_pOwnStg )
866 m_pOwnStg->CopyTo( rEleName, pNewSt->m_pOwnStg, rNewName );
867 SetError( m_pOwnStg->GetError() );
868 SetError( pNewSt->GetError() );
870 else
871 SetError( SVSTREAM_GENERALERROR );
873 return SVSTREAM_OK == GetError();
876 bool SotStorage::MoveTo( const OUString & rEleName,
877 SotStorage * pNewSt, const OUString & rNewName )
879 DBG_ASSERT( Owner(), "must be owner" );
880 DBG_ASSERT( pNewSt->Owner(), "must be owner" );
881 if( m_pOwnStg )
883 m_pOwnStg->MoveTo( rEleName, pNewSt->m_pOwnStg, rNewName );
884 SetError( m_pOwnStg->GetError() );
885 SetError( pNewSt->GetError() );
887 else
888 SetError( SVSTREAM_GENERALERROR );
890 return SVSTREAM_OK == GetError();
893 bool SotStorage::Validate()
895 DBG_ASSERT( m_bIsRoot, "Validate nur an Rootstorage" );
896 if( m_pOwnStg )
897 return m_pOwnStg->ValidateFAT();
898 else
899 return true;
902 bool SotStorage::IsOLEStorage() const
904 UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
905 return !pStg;
908 bool SotStorage::IsOLEStorage( const OUString & rFileName )
910 return Storage::IsStorageFile( rFileName );
913 bool SotStorage::IsOLEStorage( SvStream* pStream )
915 return Storage::IsStorageFile( pStream );
918 SotStorage* SotStorage::OpenOLEStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage,
919 const OUString& rEleName, StreamMode nMode )
921 sal_Int32 nEleMode = embed::ElementModes::SEEKABLEREAD;
922 if ( nMode & STREAM_WRITE )
923 nEleMode |= embed::ElementModes::WRITE;
924 if ( nMode & STREAM_TRUNC )
925 nEleMode |= embed::ElementModes::TRUNCATE;
926 if ( nMode & STREAM_NOCREATE )
927 nEleMode |= embed::ElementModes::NOCREATE;
929 SvStream* pStream = NULL;
932 uno::Reference < io::XStream > xStream = xStorage->openStreamElement( rEleName, nEleMode );
934 // TODO/LATER: should it be done this way?
935 if ( nMode & STREAM_WRITE )
937 uno::Reference < beans::XPropertySet > xStreamProps( xStream, uno::UNO_QUERY_THROW );
938 xStreamProps->setPropertyValue(
939 OUString( "MediaType" ),
940 uno::makeAny( OUString( "application/vnd.sun.star.oleobject" ) ) );
943 pStream = utl::UcbStreamHelper::CreateStream( xStream );
945 catch ( uno::Exception& )
947 //TODO/LATER: ErrorHandling
948 pStream = new SvMemoryStream;
949 pStream->SetError( ERRCODE_IO_GENERAL );
952 return new SotStorage( pStream, true );
955 sal_Int32 SotStorage::GetFormatID( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage )
957 uno::Reference< beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY );
958 if ( !xProps.is() )
959 return 0;
961 OUString aMediaType;
962 xProps->getPropertyValue("MediaType") >>= aMediaType;
963 if ( !aMediaType.isEmpty() )
965 ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
966 aDataFlavor.MimeType = aMediaType;
967 return SotExchange::GetFormat( aDataFlavor );
970 return 0;
973 sal_Int32 SotStorage::GetVersion( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage )
975 sal_Int32 nSotFormatID = SotStorage::GetFormatID( xStorage );
976 switch( nSotFormatID )
978 case SOT_FORMATSTR_ID_STARWRITER_8:
979 case SOT_FORMATSTR_ID_STARWRITER_8_TEMPLATE:
980 case SOT_FORMATSTR_ID_STARWRITERWEB_8:
981 case SOT_FORMATSTR_ID_STARWRITERGLOB_8:
982 case SOT_FORMATSTR_ID_STARDRAW_8:
983 case SOT_FORMATSTR_ID_STARDRAW_8_TEMPLATE:
984 case SOT_FORMATSTR_ID_STARIMPRESS_8:
985 case SOT_FORMATSTR_ID_STARIMPRESS_8_TEMPLATE:
986 case SOT_FORMATSTR_ID_STARCALC_8:
987 case SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE:
988 case SOT_FORMATSTR_ID_STARCHART_8:
989 case SOT_FORMATSTR_ID_STARCHART_8_TEMPLATE:
990 case SOT_FORMATSTR_ID_STARMATH_8:
991 case SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE:
992 return SOFFICE_FILEFORMAT_8;
993 case SOT_FORMATSTR_ID_STARWRITER_60:
994 case SOT_FORMATSTR_ID_STARWRITERWEB_60:
995 case SOT_FORMATSTR_ID_STARWRITERGLOB_60:
996 case SOT_FORMATSTR_ID_STARDRAW_60:
997 case SOT_FORMATSTR_ID_STARIMPRESS_60:
998 case SOT_FORMATSTR_ID_STARCALC_60:
999 case SOT_FORMATSTR_ID_STARCHART_60:
1000 case SOT_FORMATSTR_ID_STARMATH_60:
1001 return SOFFICE_FILEFORMAT_60;
1004 return 0;
1007 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */