lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / sot / source / sdstor / stg.cxx
blob435cfa2e80c4c8089045e8bb8364a047c89f3267
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 .
21 #include <sot/storinfo.hxx>
22 #include <sot/exchange.hxx>
23 #include <osl/file.hxx>
24 #include <unotools/tempfile.hxx>
25 #include <tools/stream.hxx>
26 #include <tools/debug.hxx>
28 #include <sot/stg.hxx>
29 #include "stgelem.hxx"
30 #include "stgcache.hxx"
31 #include "stgstrms.hxx"
32 #include "stgdir.hxx"
33 #include "stgio.hxx"
34 #include "stgole.hxx"
36 #include <memory>
38 static long nTmpCount = 0;
40 // The internal open mode is StreamMode::READ | StreamMode::TRUNC, which is silly
41 // by itself. It inhibits the checking of sharing modes and is used
42 // during CopyTo() and MoveTo() for opening a stream in read mode
43 // although it may be open in DENYALL mode
45 #define INTERNAL_MODE ( StreamMode::READ | StreamMode::TRUNC )
47 ///////////////////////// class StorageBase
50 StorageBase::StorageBase()
51 : m_bAutoCommit( false )
53 m_nMode = StreamMode::READ;
54 m_nError = ERRCODE_NONE;
57 StorageBase::~StorageBase()
61 // The following three methods are declared as const, since they
62 // may be called from within a const method.
64 ErrCode StorageBase::GetError() const
66 const ErrCode n = m_nError;
67 m_nError = ERRCODE_NONE;
68 return n;
71 void StorageBase::SetError( ErrCode n ) const
73 if( !m_nError )
74 m_nError = n;
77 void StorageBase::ResetError() const
79 m_nError = ERRCODE_NONE;
82 OLEStorageBase::OLEStorageBase( StgIo* p, StgDirEntry* pe, StreamMode& nMode )
83 : nStreamMode( nMode ), pIo( p ), pEntry( pe )
85 if ( p )
86 p->IncRef();
87 if( pe )
88 pe->m_nRefCnt++;
91 OLEStorageBase::~OLEStorageBase()
93 if( pEntry )
95 DBG_ASSERT( pEntry->m_nRefCnt, "RefCount under 0" );
96 if( !--pEntry->m_nRefCnt )
98 if( pEntry->m_bZombie )
99 delete pEntry;
100 else
101 pEntry->Close();
104 pEntry = nullptr;
108 if( pIo && !pIo->DecRef() )
110 delete pIo;
111 pIo = nullptr;
115 // Validate the instance for I/O
117 bool OLEStorageBase::Validate_Impl( bool bWrite ) const
119 return pIo
120 && pIo->m_pTOC
121 && pEntry
122 && !pEntry->m_bInvalid
123 && ( !bWrite || !pEntry->m_bDirect || ( nStreamMode & StreamMode::WRITE ) );
126 bool OLEStorageBase::ValidateMode_Impl( StreamMode m, StgDirEntry const * p )
128 if( m == INTERNAL_MODE )
129 return true;
130 StreamMode nCurMode = ( p && p->m_nRefCnt ) ? p->m_nMode : StreamMode::SHARE_DENYALL;
131 if( ( m & StreamMode::READWRITE ) == StreamMode::READ )
133 // only SHARE_DENYWRITE or SHARE_DENYALL allowed
134 if( ( ( m & StreamMode::SHARE_DENYWRITE )
135 && ( nCurMode & StreamMode::SHARE_DENYWRITE ) )
136 || ( ( m & StreamMode::SHARE_DENYALL )
137 && ( nCurMode & StreamMode::SHARE_DENYALL ) ) )
138 return true;
140 else
142 // only SHARE_DENYALL allowed
143 // storages open in r/o mode are OK, since only
144 // the commit may fail
145 if( ( m & StreamMode::SHARE_DENYALL )
146 && ( nCurMode & StreamMode::SHARE_DENYALL ) )
147 return true;
149 return false;
153 //////////////////////// class StorageStream
156 StorageStream::StorageStream( StgIo* p, StgDirEntry* q, StreamMode m )
157 : OLEStorageBase( p, q, m_nMode ), nPos( 0 )
159 // The dir entry may be 0; this means that the stream is invalid.
160 if( q && p )
162 if( q->m_nRefCnt == 1 )
164 q->m_nMode = m;
165 q->OpenStream( *p );
168 else
169 m &= ~StreamMode::READWRITE;
170 m_nMode = m;
173 StorageStream::~StorageStream()
175 // Do an auto-commit if the entry is open in direct mode
176 if( m_bAutoCommit )
177 Commit();
178 if( pEntry && pEntry->m_nRefCnt && pEntry->m_bDirect && (m_nMode & StreamMode::WRITE) )
179 pEntry->Commit();
182 bool StorageStream::Equals( const BaseStorageStream& rStream ) const
184 const StorageStream* pOther = dynamic_cast<const StorageStream*>( &rStream );
185 return pOther && ( pOther->pEntry == pEntry );
188 sal_uLong StorageStream::Read( void* pData, sal_uLong nSize )
190 if( Validate() )
192 pEntry->Seek( nPos );
193 nSize = pEntry->Read( pData, static_cast<sal_Int32>(nSize) );
194 pIo->MoveError( *this );
195 nPos += nSize;
197 else
198 nSize = 0;
199 return nSize;
202 sal_uLong StorageStream::Write( const void* pData, sal_uLong nSize )
204 if( Validate( true ) )
206 pEntry->Seek( nPos );
207 nSize = pEntry->Write( pData, static_cast<sal_Int32>(nSize) );
208 pIo->MoveError( *this );
209 nPos += nSize;
211 else
212 nSize = 0;
213 return nSize;
216 sal_uInt64 StorageStream::Seek( sal_uInt64 n )
218 if( Validate() )
219 return nPos = pEntry->Seek( n );
220 else
221 return n;
224 void StorageStream::Flush()
226 // Flushing means committing, since streams are never transacted
227 Commit();
230 bool StorageStream::SetSize( sal_uLong nNewSize )
232 if( Validate( true ) )
234 bool b = pEntry->SetSize( static_cast<sal_Int32>(nNewSize) );
235 pIo->MoveError( *this );
236 return b;
238 else
239 return false;
242 sal_uLong StorageStream::GetSize() const
244 if( Validate() )
245 return pEntry->GetSize();
246 return 0;
249 bool StorageStream::Commit()
251 if( !Validate() )
252 return false;
253 if( !( m_nMode & StreamMode::WRITE ) )
255 SetError( SVSTREAM_ACCESS_DENIED );
256 return false;
258 else
260 pEntry->Commit();
261 pIo->MoveError( *this );
262 return Good();
266 void StorageStream::CopyTo( BaseStorageStream* pDest )
268 if( !Validate() || !pDest || !pDest->Validate( true ) || Equals( *pDest ) )
269 return;
270 pEntry->Copy( *pDest );
271 pDest->Commit();
272 pIo->MoveError( *this );
273 SetError( pDest->GetError() );
276 bool StorageStream::Validate( bool bValidate ) const
278 bool bRet = Validate_Impl( bValidate );
279 if ( !bRet )
280 SetError( SVSTREAM_ACCESS_DENIED );
281 return bRet;
284 bool StorageStream::ValidateMode( StreamMode nMode ) const
286 bool bRet = ValidateMode_Impl( nMode );
287 if ( !bRet )
288 SetError( SVSTREAM_ACCESS_DENIED );
289 return bRet;
292 ///////////////////////// class SvStorageInfo
294 SvStorageInfo::SvStorageInfo( const StgDirEntry& rE )
296 rE.m_aEntry.GetName( aName );
297 bStorage = rE.m_aEntry.GetType() == STG_STORAGE;
298 bStream = rE.m_aEntry.GetType() == STG_STREAM;
299 nSize = bStorage ? 0 : rE.m_aEntry.GetSize();
302 /////////////////////////// class Storage
304 bool Storage::IsStorageFile( const OUString & rFileName )
306 StgIo aIo;
307 if( aIo.Open( rFileName, StreamMode::STD_READ ) )
308 return aIo.Load();
309 return false;
312 bool Storage::IsStorageFile( SvStream* pStream )
314 bool bRet = false;
316 if ( pStream )
318 StgHeader aHdr;
319 sal_uInt64 nPos = pStream->Tell();
320 bRet = ( aHdr.Load( *pStream ) && aHdr.Check() );
322 // It's not a stream error if it is too small for a OLE storage header
323 if ( pStream->GetErrorCode() == ERRCODE_IO_CANTSEEK )
324 pStream->ResetError();
325 pStream->Seek( nPos );
328 return bRet;
331 // Open the storage file. If writing is permitted and the file is not
332 // a storage file, initialize it.
335 Storage::Storage( const OUString& rFile, StreamMode m, bool bDirect )
336 : OLEStorageBase( new StgIo, nullptr, m_nMode )
337 , aName( rFile ), bIsRoot( false )
339 bool bTemp = false;
340 if( aName.isEmpty() )
342 // no name = temporary name!
343 aName = utl::TempFile::CreateTempName();
344 bTemp = true;
346 // the root storage creates the I/O system
347 m_nMode = m;
348 if( pIo->Open( aName, m ) )
350 Init( ( m & ( StreamMode::TRUNC | StreamMode::NOCREATE ) ) == StreamMode::TRUNC );
351 if( pEntry )
353 pEntry->m_bDirect = bDirect;
354 pEntry->m_nMode = m;
355 pEntry->m_bTemp = bTemp;
358 else
360 pIo->MoveError( *this );
361 pEntry = nullptr;
365 // Create a storage on a given stream.
367 Storage::Storage( SvStream& r, bool bDirect )
368 : OLEStorageBase( new StgIo, nullptr, m_nMode )
369 , bIsRoot( false )
371 m_nMode = StreamMode::READ;
372 if( r.IsWritable() )
373 m_nMode = StreamMode::READ | StreamMode::WRITE;
374 if( r.GetError() == ERRCODE_NONE )
376 pIo->SetStrm( &r, false );
377 sal_uInt64 nSize = r.TellEnd();
378 r.Seek( 0 );
379 // Initializing is OK if the stream is empty
380 Init( nSize == 0 );
381 if( pEntry )
383 pEntry->m_bDirect = bDirect;
384 pEntry->m_nMode = m_nMode;
386 pIo->MoveError( *this );
388 else
390 SetError( r.GetError() );
391 pEntry = nullptr;
396 Storage::Storage( UCBStorageStream& rStrm, bool bDirect )
397 : OLEStorageBase( new StgIo, nullptr, m_nMode ), bIsRoot( false )
399 m_nMode = StreamMode::READ;
401 if ( rStrm.GetError() != ERRCODE_NONE )
403 SetError( rStrm.GetError() );
404 pEntry = nullptr;
405 return;
408 SvStream* pStream = rStrm.GetModifySvStream();
409 if ( !pStream )
411 OSL_FAIL( "UCBStorageStream can not provide SvStream implementation!" );
412 SetError( SVSTREAM_GENERALERROR );
413 pEntry = nullptr;
414 return;
417 if( pStream->IsWritable() )
418 m_nMode = StreamMode::READ | StreamMode::WRITE;
420 pIo->SetStrm( &rStrm );
422 sal_uInt64 nSize = pStream->TellEnd();
423 pStream->Seek( 0 );
424 // Initializing is OK if the stream is empty
425 Init( nSize == 0 );
426 if( pEntry )
428 pEntry->m_bDirect = bDirect;
429 pEntry->m_nMode = m_nMode;
432 pIo->MoveError( *this );
436 // Perform common code for both ctors above.
438 void Storage::Init( bool bCreate )
440 pEntry = nullptr;
441 bool bHdrLoaded = false;
442 bIsRoot = true;
444 OSL_ENSURE( pIo, "The pointer may not be empty at this point!" );
445 if( pIo->Good() && pIo->GetStrm() )
447 sal_uInt64 nSize = pIo->GetStrm()->TellEnd();
448 pIo->GetStrm()->Seek( 0 );
449 if( nSize )
451 bHdrLoaded = pIo->Load();
452 if( !bHdrLoaded && !bCreate )
454 // File is not a storage and not empty; do not destroy!
455 SetError( SVSTREAM_FILEFORMAT_ERROR );
456 return;
460 // file is a storage, empty or should be overwritten
461 pIo->ResetError();
462 // we have to set up the data structures, since
463 // the file is empty
464 if( !bHdrLoaded )
465 pIo->Init();
466 if( pIo->Good() && pIo->m_pTOC )
468 pEntry = pIo->m_pTOC->GetRoot();
469 pEntry->m_nRefCnt++;
473 // Internal ctor
475 Storage::Storage( StgIo* p, StgDirEntry* q, StreamMode m )
476 : OLEStorageBase( p, q, m_nMode ), bIsRoot( false )
478 if( q )
479 q->m_aEntry.GetName( aName );
480 else
481 m &= ~StreamMode::READWRITE;
482 m_nMode = m;
483 if( q && q->m_nRefCnt == 1 )
484 q->m_nMode = m;
487 Storage::~Storage()
489 // Invalidate all open substorages
490 if( m_bAutoCommit )
491 Commit();
492 if( pEntry )
494 // Do an auto-commit if the entry is open in direct mode
495 if( pEntry->m_nRefCnt && pEntry->m_bDirect && (m_nMode & StreamMode::WRITE) )
496 Commit();
497 if( pEntry->m_nRefCnt == 1 )
498 pEntry->Invalidate(false);
500 // close the stream is root storage
501 if( bIsRoot )
502 pIo->Close();
503 // remove the file if temporary root storage
504 if( bIsRoot && pEntry && pEntry->m_bTemp )
506 osl::File::remove( GetName() );
510 const OUString& Storage::GetName() const
512 if( !bIsRoot && Validate() )
513 pEntry->m_aEntry.GetName( const_cast<Storage*>(this)->aName );
514 return aName;
517 // Fill in the info list for this storage
519 void Storage::FillInfoList( SvStorageInfoList* pList ) const
521 if( Validate() && pList )
523 StgIterator aIter( *pEntry );
524 StgDirEntry* p = aIter.First();
525 while( p )
527 if( !p->m_bInvalid )
529 SvStorageInfo aInfo( *p );
530 pList->push_back( aInfo );
532 p = aIter.Next();
537 // Open or create a substorage
539 BaseStorage* Storage::OpenUCBStorage( const OUString& rName, StreamMode m, bool bDirect )
541 OSL_FAIL("Not supported!");
542 return OpenStorage( rName, m, bDirect );
545 BaseStorage* Storage::OpenOLEStorage( const OUString& rName, StreamMode m, bool bDirect )
547 return OpenStorage( rName, m, bDirect );
550 BaseStorage* Storage::OpenStorage( const OUString& rName, StreamMode m, bool bDirect )
552 if( !Validate() || !ValidateMode( m ) )
553 return new Storage( pIo, nullptr, m );
554 if( bDirect && !pEntry->m_bDirect )
555 bDirect = false;
557 StgDirEntry* p = StgDirStrm::Find( *pEntry, rName );
558 if( !p )
560 if( !( m & StreamMode::NOCREATE ) )
562 bool bTemp = false;
563 // create a new storage
564 OUString aNewName = rName;
565 if( aNewName.isEmpty() )
567 aNewName = "Temp Stg " + OUString::number( ++nTmpCount );
568 bTemp = true;
570 p = pIo->m_pTOC->Create( *pEntry, aNewName, STG_STORAGE );
571 if( p )
572 p->m_bTemp = bTemp;
574 if( !p )
575 pIo->SetError( ( m & StreamMode::WRITE )
576 ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
578 else if( !ValidateMode( m, p ) )
579 p = nullptr;
580 if( p && p->m_aEntry.GetType() != STG_STORAGE )
582 pIo->SetError( SVSTREAM_FILE_NOT_FOUND );
583 p = nullptr;
586 // Either direct or transacted mode is supported
587 if( p && pEntry->m_nRefCnt == 1 )
588 p->m_bDirect = bDirect;
590 // Don't check direct conflict if opening readonly
591 if( p && (m & StreamMode::WRITE ))
593 if( p->m_bDirect != bDirect )
594 SetError( SVSTREAM_ACCESS_DENIED );
596 Storage* pStg = new Storage( pIo, p, m );
597 pIo->MoveError( *pStg );
598 if( m & StreamMode::WRITE ) pStg->m_bAutoCommit = true;
599 return pStg;
602 // Open a stream
604 BaseStorageStream* Storage::OpenStream( const OUString& rName, StreamMode m, bool )
606 if( !Validate() || !ValidateMode( m ) )
607 return new StorageStream( pIo, nullptr, m );
608 StgDirEntry* p = StgDirStrm::Find( *pEntry, rName );
609 bool bTemp = false;
610 if( !p )
612 if( !( m & StreamMode::NOCREATE ) )
614 // create a new stream
615 // make a name if the stream is temporary (has no name)
616 OUString aNewName( rName );
617 if( aNewName.isEmpty() )
619 aNewName = "Temp Strm " + OUString::number( ++nTmpCount );
620 bTemp = true;
622 p = pIo->m_pTOC->Create( *pEntry, aNewName, STG_STREAM );
624 if( !p )
625 pIo->SetError( ( m & StreamMode::WRITE )
626 ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
628 else if( !ValidateMode( m, p ) )
629 p = nullptr;
630 if( p && p->m_aEntry.GetType() != STG_STREAM )
632 pIo->SetError( SVSTREAM_FILE_NOT_FOUND );
633 p = nullptr;
635 if( p )
637 p->m_bTemp = bTemp;
638 p->m_bDirect = pEntry->m_bDirect;
640 StorageStream* pStm = new StorageStream( pIo, p, m );
641 if( p && !p->m_bDirect )
642 pStm->SetAutoCommit( true );
643 pIo->MoveError( *pStm );
644 return pStm;
647 // Delete a stream or substorage by setting the temp bit.
649 void Storage::Remove( const OUString& rName )
651 if( !Validate( true ) )
652 return;
653 StgDirEntry* p = StgDirStrm::Find( *pEntry, rName );
654 if( p )
656 p->Invalidate( true );
658 else
660 SetError( SVSTREAM_FILE_NOT_FOUND );
664 // Copy one element
666 bool Storage::CopyTo( const OUString& rElem, BaseStorage* pDest, const OUString& rNew )
668 if( !Validate() || !pDest || !pDest->Validate( true ) )
669 return false;
670 StgDirEntry* pElem = StgDirStrm::Find( *pEntry, rElem );
671 if( pElem )
673 if( pElem->m_aEntry.GetType() == STG_STORAGE )
675 // copy the entire storage
676 tools::SvRef<BaseStorage> p1 = OpenStorage( rElem, INTERNAL_MODE );
677 tools::SvRef<BaseStorage> p2 = pDest->OpenOLEStorage( rNew, StreamMode::WRITE | StreamMode::SHARE_DENYALL, pEntry->m_bDirect );
679 if ( p2 )
681 ErrCode nTmpErr = p2->GetError();
682 if( !nTmpErr )
684 p2->SetClassId( p1->GetClassId() );
685 p1->CopyTo( p2.get() );
686 SetError( p1->GetError() );
688 nTmpErr = p2->GetError();
689 if( !nTmpErr )
690 p2->Commit();
691 else
692 pDest->SetError( nTmpErr );
694 else
695 pDest->SetError( nTmpErr );
698 return Good() && pDest->Good();
700 else
702 // stream copy
703 tools::SvRef<BaseStorageStream> p1 = OpenStream( rElem, INTERNAL_MODE );
704 tools::SvRef<BaseStorageStream> p2 = pDest->OpenStream( rNew, StreamMode::WRITE | StreamMode::SHARE_DENYALL, pEntry->m_bDirect );
706 if ( p2 )
708 ErrCode nTmpErr = p2->GetError();
709 if( !nTmpErr )
711 p1->CopyTo( p2.get() );
712 SetError( p1->GetError() );
714 nTmpErr = p2->GetError();
715 if( !nTmpErr )
716 p2->Commit();
717 else
718 pDest->SetError( nTmpErr );
720 else
721 pDest->SetError( nTmpErr );
724 return Good() && pDest->Good();
727 SetError( SVSTREAM_FILE_NOT_FOUND );
728 return false;
731 bool Storage::CopyTo( BaseStorage* pDest ) const
733 if( !Validate() || !pDest || !pDest->Validate( true ) || Equals( *pDest ) )
735 SetError( SVSTREAM_ACCESS_DENIED );
736 return false;
738 Storage* pThis = const_cast<Storage*>(this);
739 pDest->SetClassId( GetClassId() );
740 pDest->SetDirty();
741 SvStorageInfoList aList;
742 FillInfoList( &aList );
743 bool bRes = true;
744 for( size_t i = 0; i < aList.size() && bRes; i++ )
746 SvStorageInfo& rInfo = aList[ i ];
747 bRes = pThis->CopyTo( rInfo.GetName(), pDest, rInfo.GetName() );
749 if( !bRes )
750 SetError( pDest->GetError() );
751 return Good() && pDest->Good();
754 bool Storage::IsStorage( const OUString& rName ) const
756 if( Validate() )
758 StgDirEntry* p = StgDirStrm::Find( *pEntry, rName );
759 if( p )
760 return p->m_aEntry.GetType() == STG_STORAGE;
762 return false;
765 bool Storage::IsStream( const OUString& rName ) const
767 if( Validate() )
769 StgDirEntry* p = StgDirStrm::Find( *pEntry, rName );
770 if( p )
771 return p->m_aEntry.GetType() == STG_STREAM;
773 return false;
776 bool Storage::IsContained( const OUString& rName ) const
778 if( Validate() )
779 return StgDirStrm::Find( *pEntry, rName ) != nullptr;
780 else
781 return false;
784 // Commit all sub-elements within this storage. If this is
785 // the root, commit the FAT, the TOC and the header as well.
787 bool Storage::Commit()
789 bool bRes = true;
790 if( !Validate() )
791 return false;
792 if( !( m_nMode & StreamMode::WRITE ) )
794 SetError( SVSTREAM_ACCESS_DENIED );
795 return false;
797 else
799 // Also commit the sub-streams and Storages
800 StgIterator aIter( *pEntry );
801 for( StgDirEntry* p = aIter.First(); p && bRes; p = aIter.Next() )
802 bRes = p->Commit();
803 if( bRes && bIsRoot )
805 bRes = pEntry->Commit();
806 if( bRes )
807 bRes = pIo->CommitAll();
809 pIo->MoveError( *this );
811 return bRes;
814 bool Storage::Revert()
816 return true;
819 ///////////////////////////// OLE Support
821 // Set the storage type
823 void Storage::SetClass( const SvGlobalName & rClass,
824 SotClipboardFormatId nOriginalClipFormat,
825 const OUString & rUserTypeName )
827 if( Validate( true ) )
829 // set the class name in the root entry
830 pEntry->m_aEntry.SetClassId( rClass.GetCLSID() );
831 pEntry->SetDirty();
832 // then create the streams
833 StgCompObjStream aCompObj( *this, true );
834 aCompObj.GetClsId() = rClass.GetCLSID();
835 aCompObj.GetCbFormat() = nOriginalClipFormat;
836 aCompObj.GetUserName() = rUserTypeName;
837 if( !aCompObj.Store() )
838 SetError( aCompObj.GetError() );
839 else
841 StgOleStream aOle(*this);
842 if( !aOle.Store() )
843 SetError( aOle.GetError() );
846 else
847 SetError( SVSTREAM_ACCESS_DENIED );
850 SvGlobalName Storage::GetClassName()
852 StgCompObjStream aCompObj( *this, false );
853 if( aCompObj.Load() )
854 return SvGlobalName( aCompObj.GetClsId() );
855 pIo->ResetError();
857 if ( pEntry )
858 return SvGlobalName( pEntry->m_aEntry.GetClassId() );
860 return SvGlobalName();
863 SotClipboardFormatId Storage::GetFormat()
865 StgCompObjStream aCompObj( *this, false );
866 if( aCompObj.Load() )
867 return aCompObj.GetCbFormat();
868 pIo->ResetError();
869 return SotClipboardFormatId::NONE;
872 OUString Storage::GetUserName()
874 StgCompObjStream aCompObj( *this, false );
875 if( aCompObj.Load() )
876 return aCompObj.GetUserName();
877 pIo->ResetError();
878 return OUString();
881 bool Storage::ValidateFAT()
883 Link<StgLinkArg&,void> aLink = StgIo::GetErrorLink();
884 FatError nErr = pIo->ValidateFATs();
885 StgIo::SetErrorLink( aLink );
886 return nErr == FatError::Ok;
889 void Storage::SetDirty()
891 if ( pEntry )
892 pEntry->SetDirty();
895 void Storage::SetClassId( const ClsId& rId )
897 if ( pEntry )
898 pEntry->m_aEntry.SetClassId( rId );
901 const ClsId& Storage::GetClassId() const
903 if ( pEntry )
904 return pEntry->m_aEntry.GetClassId();
906 static ClsId aDummyId = {0,0,0,{0,0,0,0,0,0,0,0}};
907 return aDummyId;
910 bool Storage::Validate( bool bValidate ) const
912 bool bRet = Validate_Impl( bValidate );
913 if ( !bRet )
914 SetError( SVSTREAM_ACCESS_DENIED );
915 return bRet;
918 bool Storage::ValidateMode( StreamMode nMode ) const
920 bool bRet = ValidateMode_Impl( nMode );
921 if ( !bRet )
922 SetError( SVSTREAM_ACCESS_DENIED );
923 return bRet;
926 bool Storage::ValidateMode( StreamMode nMode, StgDirEntry const * p ) const
928 bool bRet = ValidateMode_Impl( nMode, p );
929 if ( !bRet )
930 SetError( SVSTREAM_ACCESS_DENIED );
931 return bRet;
934 bool Storage::Equals( const BaseStorage& rStorage ) const
936 const Storage* pOther = dynamic_cast<const Storage*>( &rStorage );
937 return pOther && ( pOther->pEntry == pEntry );
940 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */