LCOV - code coverage report
Current view: top level - sot/source/sdstor - stg.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 396 571 69.4 %
Date: 2014-11-03 Functions: 62 93 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : 
      21             : #include <sot/storinfo.hxx>
      22             : #include <osl/file.hxx>
      23             : #include <unotools/tempfile.hxx>
      24             : #include <tools/stream.hxx>
      25             : #include <tools/debug.hxx>
      26             : 
      27             : #include "sot/stg.hxx"
      28             : #include "stgelem.hxx"
      29             : #include "stgcache.hxx"
      30             : #include "stgstrms.hxx"
      31             : #include "stgdir.hxx"
      32             : #include "stgio.hxx"
      33             : #include "stgole.hxx"
      34             : 
      35             : static long nTmpCount = 0;
      36             : 
      37             : // The internal open mode is STREAM_READ | STREAM_TRUNC, which is silly
      38             : // by itself. It inhibits the checking of sharing modes and is used
      39             : // during CopyTo() and MoveTo() for opening a stream in read mode
      40             : // although it may be open in DENYALL mode
      41             : 
      42             : #define INTERNAL_MODE ( STREAM_READ | STREAM_TRUNC )
      43             : 
      44             : ///////////////////////// class StorageBase
      45             : 
      46        3460 : TYPEINIT0( StorageBase );
      47           0 : TYPEINIT1( BaseStorageStream, StorageBase );
      48        3460 : TYPEINIT1( BaseStorage, StorageBase );
      49             : 
      50       17532 : StorageBase::StorageBase()
      51       17532 :     : m_bAutoCommit( false )
      52             : {
      53       17532 :     m_nMode  = STREAM_READ;
      54       17532 :     m_nError = SVSTREAM_OK;
      55       17532 : }
      56             : 
      57       17532 : StorageBase::~StorageBase()
      58             : {
      59       17532 : }
      60             : 
      61             : // The following three methods are declared as const, since they
      62             : // may be called from within a const method.
      63             : 
      64     3826968 : sal_uLong StorageBase::GetError() const
      65             : {
      66     3826968 :     sal_uLong n = m_nError;
      67     3826968 :     ((StorageBase*) this)->m_nError = SVSTREAM_OK;
      68     3826968 :     return n;
      69             : }
      70             : 
      71       23100 : void StorageBase::SetError( sal_uLong n ) const
      72             : {
      73       23100 :     if( !m_nError )
      74       22974 :         ((StorageBase*) this)->m_nError = n;
      75       23100 : }
      76             : 
      77       12696 : void StorageBase::ResetError() const
      78             : {
      79       12696 :     ((StorageBase*) this)->m_nError = SVSTREAM_OK;
      80       12696 : }
      81             : 
      82             : // Retrieve the underlying SvStream for info purposes
      83             : 
      84           0 : const SvStream* OLEStorageBase::GetSvStream_Impl() const
      85             : {
      86           0 :     return pIo ? pIo->GetStrm() : NULL;
      87             : }
      88             : 
      89       13830 : OLEStorageBase::OLEStorageBase( StgIo* p, StgDirEntry* pe, StreamMode& nMode )
      90       13830 :     : nStreamMode( nMode ), pIo( p ), pEntry( pe )
      91             : {
      92       13830 :     if ( p )
      93       13830 :         p->IncRef();
      94       13830 :     if( pe )
      95       11580 :         pe->nRefCnt++;
      96       13830 : }
      97             : 
      98       13830 : OLEStorageBase::~OLEStorageBase()
      99             : {
     100       13830 :     if( pEntry )
     101             :     {
     102             :         DBG_ASSERT( pEntry->nRefCnt, "RefCount unter 0" );
     103       12808 :         if( !--pEntry->nRefCnt )
     104             :         {
     105       12762 :             if( pEntry->bZombie )
     106           0 :                 delete pEntry;
     107             :             else
     108       12762 :                 pEntry->Close();
     109             :         }
     110             : 
     111       12808 :         pEntry = NULL;
     112             :     }
     113             : 
     114             : 
     115       13830 :     if( pIo && !pIo->DecRef() )
     116             :     {
     117        2048 :         delete pIo;
     118        2048 :         pIo = NULL;
     119             :     }
     120       13830 : }
     121             : 
     122             : // Validate the instance for I/O
     123             : 
     124     3880608 : bool OLEStorageBase::Validate_Impl( bool bWrite ) const
     125             : {
     126     3880608 :     if( pIo
     127     3880608 :         && pIo->pTOC
     128     3880488 :         && pEntry
     129     3879968 :         && !pEntry->bInvalid
     130     3879968 :         &&  ( !bWrite || !pEntry->bDirect || ( nStreamMode & STREAM_WRITE ) ) )
     131     3879968 :             return true;
     132         640 :     return false;
     133             : }
     134             : 
     135       19206 : bool OLEStorageBase::ValidateMode_Impl( StreamMode m, StgDirEntry* p ) const
     136             : {
     137       19206 :     if( m == INTERNAL_MODE )
     138        3956 :         return true;
     139       15250 :     sal_uInt16 nCurMode = ( p && p->nRefCnt ) ? p->nMode : 0xFFFF;
     140       15250 :     if( ( m & 3 ) == STREAM_READ )
     141             :     {
     142             :         // only SHARE_DENYWRITE or SHARE_DENYALL allowed
     143        9814 :         if( ( ( m & STREAM_SHARE_DENYWRITE )
     144          96 :            && ( nCurMode & STREAM_SHARE_DENYWRITE ) )
     145        9718 :          || ( ( m & STREAM_SHARE_DENYALL )
     146        9718 :            && ( nCurMode & STREAM_SHARE_DENYALL ) ) )
     147        9814 :             return true;
     148             :     }
     149             :     else
     150             :     {
     151             :         // only SHARE_DENYALL allowed
     152             :         // storages open in r/o mode are OK, since only
     153             :         // the commit may fail
     154        5436 :         if( ( m & STREAM_SHARE_DENYALL )
     155        5436 :          && ( nCurMode & STREAM_SHARE_DENYALL ) )
     156        5436 :             return true;
     157             :     }
     158           0 :     return false;
     159             : }
     160             : 
     161             : 
     162             : //////////////////////// class StorageStream
     163             : 
     164        7664 : TYPEINIT1( StorageStream, BaseStorageStream );
     165             : 
     166       11214 : StorageStream::StorageStream( StgIo* p, StgDirEntry* q, StreamMode m )
     167       11214 :              : OLEStorageBase( p, q, m_nMode ), nPos( 0L )
     168             : {
     169             :     // The dir entry may be 0; this means that the stream is invalid.
     170       11214 :     if( q && p )
     171             :     {
     172       22024 :         if( q->nRefCnt == 1 )
     173             :         {
     174       11006 :             q->nMode = m;
     175       11006 :             q->OpenStream( *p );
     176             :         }
     177             :     }
     178             :     else
     179         202 :         m &= ~STREAM_READWRITE;
     180       11214 :     m_nMode = m;
     181       11214 : }
     182             : 
     183       33642 : StorageStream::~StorageStream()
     184             : {
     185             :     // Do an auto-commit if the entry is open in direct mode
     186       11214 :     if( m_bAutoCommit )
     187       10950 :         Commit();
     188       11214 :     if( pEntry && pEntry->nRefCnt && pEntry->bDirect && (m_nMode & STREAM_WRITE) )
     189           8 :         pEntry->Commit();
     190       22428 : }
     191             : 
     192        1916 : bool StorageStream::Equals( const BaseStorageStream& rStream ) const
     193             : {
     194        1916 :     const StorageStream* pOther = PTR_CAST( StorageStream, &rStream );
     195        1916 :     return pOther && ( pOther->pEntry == pEntry );
     196             : }
     197             : 
     198     2181092 : sal_uLong StorageStream::Read( void* pData, sal_uLong nSize )
     199             : {
     200     2181092 :     if( Validate() )
     201             :     {
     202     2180640 :         pEntry->Seek( nPos );
     203     2180640 :         nSize = pEntry->Read( pData, (sal_Int32) nSize );
     204     2180640 :         pIo->MoveError( *this );
     205     2180640 :         nPos += nSize;
     206             :     }
     207             :     else
     208         452 :         nSize = 0L;
     209     2181092 :     return nSize;
     210             : }
     211             : 
     212       21446 : sal_uLong StorageStream::Write( const void* pData, sal_uLong nSize )
     213             : {
     214       21446 :     if( Validate( true ) )
     215             :     {
     216       21446 :         pEntry->Seek( nPos );
     217       21446 :         nSize = pEntry->Write( pData, (sal_Int32) nSize );
     218       21446 :         pIo->MoveError( *this );
     219       21446 :         nPos += nSize;
     220             :     }
     221             :     else
     222           0 :         nSize = 0L;
     223       21446 :     return nSize;
     224             : }
     225             : 
     226     1602922 : sal_uInt64 StorageStream::Seek( sal_uInt64 n )
     227             : {
     228     1602922 :     if( Validate() )
     229     1602914 :         return nPos = pEntry->Seek( n );
     230             :     else
     231           8 :         return n;
     232             : }
     233             : 
     234         966 : void StorageStream::Flush()
     235             : {
     236             :     // Flushing means committing, since streams are never transacted
     237         966 :     Commit();
     238         966 : }
     239             : 
     240        2066 : bool StorageStream::SetSize( sal_uLong nNewSize )
     241             : {
     242        2066 :     if( Validate( true ) )
     243             :     {
     244        2066 :         bool b = pEntry->SetSize( (sal_Int32) nNewSize );
     245        2066 :         pIo->MoveError( *this );
     246        2066 :         return b;
     247             :     }
     248             :     else
     249           0 :         return false;
     250             : }
     251             : 
     252       23366 : sal_uLong StorageStream::GetSize() const
     253             : {
     254       23366 :     if( Validate() )
     255       23310 :         return pEntry->GetSize();
     256          56 :     return 0;
     257             : }
     258             : 
     259       15902 : bool StorageStream::Commit()
     260             : {
     261       15902 :     if( !Validate() )
     262           0 :         return false;
     263       15902 :     if( !( m_nMode & STREAM_WRITE ) )
     264             :     {
     265        6558 :         SetError( SVSTREAM_ACCESS_DENIED );
     266        6558 :         return false;
     267             :     }
     268             :     else
     269             :     {
     270        9344 :         pEntry->Commit();
     271        9344 :         pIo->MoveError( *this );
     272        9344 :         return Good();
     273             :     }
     274             : }
     275             : 
     276           0 : bool StorageStream::Revert()
     277             : {
     278           0 :     bool bResult = false;
     279             : 
     280           0 :     if ( Validate() )
     281             :     {
     282           0 :         pEntry->Revert();
     283           0 :         pIo->MoveError( *this );
     284           0 :         bResult = Good();
     285             :     }
     286             : 
     287           0 :     return bResult;
     288             : }
     289             : 
     290        1916 : bool StorageStream::CopyTo( BaseStorageStream* pDest )
     291             : {
     292        1916 :     if( !Validate() || !pDest || !pDest->Validate( true ) || Equals( *pDest ) )
     293           0 :         return false;
     294        1916 :     pEntry->Copy( *pDest );
     295        1916 :     pDest->Commit();
     296        1916 :     pIo->MoveError( *this );
     297        1916 :     SetError( pDest->GetError() );
     298        1916 :     return Good() && pDest->Good();
     299             : }
     300             : 
     301           0 : const SvStream* StorageStream::GetSvStream() const
     302             : {
     303           0 :     return GetSvStream_Impl();
     304             : }
     305             : 
     306     3850626 : bool StorageStream::Validate( bool bValidate ) const
     307             : {
     308     3850626 :     bool bRet = Validate_Impl( bValidate );
     309     3850626 :     if ( !bRet )
     310         516 :         SetError( SVSTREAM_ACCESS_DENIED );
     311     3850626 :     return bRet;
     312             : }
     313             : 
     314           0 : bool StorageStream::ValidateMode( StreamMode nMode ) const
     315             : {
     316           0 :     bool bRet = ValidateMode_Impl( nMode, NULL );
     317           0 :     if ( !bRet )
     318           0 :         SetError( SVSTREAM_ACCESS_DENIED );
     319           0 :     return bRet;
     320             : }
     321             : 
     322             : ///////////////////////// class SvStorageInfo
     323             : 
     324       10202 : SvStorageInfo::SvStorageInfo( const StgDirEntry& rE )
     325             : {
     326       10202 :     rE.aEntry.GetName( aName );
     327       10202 :     bStorage = rE.aEntry.GetType() == STG_STORAGE;
     328       10202 :     bStream  = rE.aEntry.GetType() == STG_STREAM;
     329       10202 :     nSize    = bStorage ? 0 : rE.aEntry.GetSize();
     330       10202 : }
     331             : 
     332             : /////////////////////////// class Storage
     333             : 
     334          34 : bool Storage::IsStorageFile( const OUString & rFileName )
     335             : {
     336          34 :     StgIo aIo;
     337          34 :     if( aIo.Open( rFileName, STREAM_STD_READ ) )
     338          34 :         return aIo.Load();
     339           0 :     return false;
     340             : }
     341             : 
     342        1486 : bool Storage::IsStorageFile( SvStream* pStream )
     343             : {
     344        1486 :     bool bRet = false;
     345             : 
     346        1486 :     if ( pStream )
     347             :     {
     348        1486 :         StgHeader aHdr;
     349        1486 :         sal_uLong nPos = pStream->Tell();
     350        1486 :         bRet = ( aHdr.Load( *pStream ) && aHdr.Check() );
     351             : 
     352             :         // It's not a stream error if it is too small for a OLE storage header
     353        1486 :         if ( pStream->GetErrorCode() == ERRCODE_IO_CANTSEEK )
     354           2 :             pStream->ResetError();
     355        1486 :         pStream->Seek( nPos );
     356             :     }
     357             : 
     358        1486 :     return bRet;
     359             : }
     360             : 
     361             : // Open the storage file. If writing is permitted and the file is not
     362             : // a storage file, initialize it.
     363             : 
     364        6070 : TYPEINIT1( Storage, BaseStorage );
     365             : 
     366           0 : Storage::Storage( const OUString& rFile, StreamMode m, bool bDirect )
     367           0 :     : OLEStorageBase( new StgIo, NULL, m_nMode )
     368           0 :     , aName( rFile ), bIsRoot( false )
     369             : {
     370           0 :     bool bTemp = false;
     371           0 :     if( aName.isEmpty() )
     372             :     {
     373             :         // no name = temporary name!
     374           0 :         aName = utl::TempFile::CreateTempName();
     375           0 :         bTemp = true;
     376             :     }
     377             :     // the root storage creates the I/O system
     378           0 :     m_nMode = m;
     379           0 :     if( pIo->Open( aName, m ) )
     380             :     {
     381           0 :         Init( ( m & ( STREAM_TRUNC | STREAM_NOCREATE ) ) == STREAM_TRUNC );
     382           0 :         if( pEntry )
     383             :         {
     384           0 :             pEntry->bDirect = bDirect;
     385           0 :             pEntry->nMode = m;
     386           0 :             pEntry->bTemp = bTemp;
     387             :         }
     388             :     }
     389             :     else
     390             :     {
     391           0 :         pIo->MoveError( *this );
     392           0 :         pEntry = NULL;
     393             :     }
     394           0 : }
     395             : 
     396             : // Create a storage on a given stream.
     397             : 
     398        2048 : Storage::Storage( SvStream& r, bool bDirect )
     399        2048 :     : OLEStorageBase( new StgIo, NULL, m_nMode )
     400        4096 :     , bIsRoot( false )
     401             : {
     402        2048 :     m_nMode = STREAM_READ;
     403        2048 :     if( r.IsWritable() )
     404        2038 :         m_nMode = STREAM_READ | STREAM_WRITE;
     405        2048 :     if( r.GetError() == SVSTREAM_OK )
     406             :     {
     407        2020 :         pIo->SetStrm( &r, false );
     408        2020 :         sal_uLong nSize = r.Seek( STREAM_SEEK_TO_END );
     409        2020 :         r.Seek( 0L );
     410             :         // Initializing is OK if the stream is empty
     411        2020 :         Init( nSize == 0 );
     412        2020 :         if( pEntry )
     413             :         {
     414        1228 :             pEntry->bDirect = bDirect;
     415        1228 :             pEntry->nMode = m_nMode;
     416             :         }
     417        2020 :         pIo->MoveError( *this );
     418             :     }
     419             :     else
     420             :     {
     421          28 :         SetError( r.GetError() );
     422          28 :         pEntry = NULL;
     423             :     }
     424        2048 : }
     425             : 
     426             : 
     427           0 : Storage::Storage( UCBStorageStream& rStrm, bool bDirect )
     428           0 :        : OLEStorageBase( new StgIo, NULL, m_nMode ), bIsRoot( false )
     429             : {
     430           0 :     m_nMode = STREAM_READ;
     431             : 
     432           0 :     if ( rStrm.GetError() != SVSTREAM_OK )
     433             :     {
     434           0 :         SetError( rStrm.GetError() );
     435           0 :         pEntry = NULL;
     436           0 :         return;
     437             :     }
     438             : 
     439           0 :     SvStream* pStream = rStrm.GetModifySvStream();
     440           0 :     if ( !pStream )
     441             :     {
     442             :         OSL_FAIL( "UCBStorageStream can not provide SvStream implementation!\n" );
     443           0 :         SetError( SVSTREAM_GENERALERROR );
     444           0 :         pEntry = NULL;
     445           0 :         return;
     446             :     }
     447             : 
     448           0 :     if( pStream->IsWritable() )
     449           0 :         m_nMode = STREAM_READ | STREAM_WRITE;
     450             : 
     451           0 :     pIo->SetStrm( &rStrm );
     452             : 
     453           0 :     sal_uLong nSize = pStream->Seek( STREAM_SEEK_TO_END );
     454           0 :     pStream->Seek( 0L );
     455             :     // Initializing is OK if the stream is empty
     456           0 :     Init( nSize == 0 );
     457           0 :     if( pEntry )
     458             :     {
     459           0 :         pEntry->bDirect = bDirect;
     460           0 :         pEntry->nMode = m_nMode;
     461             :     }
     462             : 
     463           0 :     pIo->MoveError( *this );
     464             : }
     465             : 
     466             : 
     467             : // Perform common code for both ctors above.
     468             : 
     469        2020 : void Storage::Init( bool bCreate )
     470             : {
     471        2020 :     pEntry = NULL;
     472        2020 :     bool bHdrLoaded = false;
     473        2020 :     bIsRoot = true;
     474             : 
     475             :     OSL_ENSURE( pIo, "The pointer may not be empty at this point!" );
     476        2020 :     if( pIo->Good() && pIo->GetStrm() )
     477             :     {
     478        2020 :         sal_uLong nSize = pIo->GetStrm()->Seek( STREAM_SEEK_TO_END );
     479        2020 :         pIo->GetStrm()->Seek( 0L );
     480        2020 :         if( nSize )
     481             :         {
     482        1669 :             bHdrLoaded = pIo->Load();
     483        1669 :             if( !bHdrLoaded && !bCreate  )
     484             :             {
     485             :                 // File is not a storage and not empty; do not destroy!
     486         792 :                 SetError( SVSTREAM_FILEFORMAT_ERROR );
     487        2812 :                 return;
     488             :             }
     489             :         }
     490             :     }
     491             :     // file is a storage, empty or should be overwritten
     492        1228 :     pIo->ResetError();
     493             :     // we have to set up the data structures, since
     494             :     // the file is empty
     495        1228 :     if( !bHdrLoaded )
     496         351 :         pIo->Init();
     497        1228 :     if( pIo->Good() && pIo->pTOC )
     498             :     {
     499        1228 :         pEntry = pIo->pTOC->GetRoot();
     500        1228 :         pEntry->nRefCnt++;
     501             :     }
     502             : }
     503             : 
     504             : // Internal ctor
     505             : 
     506         568 : Storage::Storage( StgIo* p, StgDirEntry* q, StreamMode m )
     507         568 :        : OLEStorageBase( p, q, m_nMode ), bIsRoot( false )
     508             : {
     509         568 :     if( q )
     510         568 :         q->aEntry.GetName( aName );
     511             :     else
     512           0 :         m &= ~STREAM_READWRITE;
     513         568 :     m_nMode   = m;
     514         568 :     if( q && q->nRefCnt == 1 )
     515         528 :         q->nMode = m;
     516         568 : }
     517             : 
     518        7848 : Storage::~Storage()
     519             : {
     520             :     // Invalidate all open substorages
     521        2616 :     if( m_bAutoCommit )
     522         394 :         Commit();
     523        2616 :     if( pEntry )
     524             :     {
     525             :         // Do an auto-commit if the entry is open in direct mode
     526        1796 :         if( pEntry->nRefCnt && pEntry->bDirect && (m_nMode & STREAM_WRITE) )
     527          30 :             Commit();
     528        1796 :         if( pEntry->nRefCnt == 1 )
     529        1756 :             pEntry->Invalidate();
     530             :     }
     531             :     // close the stream is root storage
     532        2616 :     if( bIsRoot )
     533        2020 :         pIo->Close();
     534             :     // remove the file if temporary root storage
     535        2616 :     if( bIsRoot && pEntry && pEntry->bTemp )
     536             :     {
     537           0 :         osl::File::remove( GetName() );
     538             :     }
     539        5232 : }
     540             : 
     541         268 : const OUString& Storage::GetName() const
     542             : {
     543         268 :     if( !bIsRoot && Validate() )
     544         260 :         pEntry->aEntry.GetName( ((Storage*) this)->aName );
     545         268 :     return aName;
     546             : }
     547             : 
     548             : // Fill in the info list for this storage
     549             : 
     550        1950 : void Storage::FillInfoList( SvStorageInfoList* pList ) const
     551             : {
     552        1950 :     if( Validate() && pList )
     553             :     {
     554        1832 :         StgIterator aIter( *pEntry );
     555        1832 :         StgDirEntry* p = aIter.First();
     556       13866 :         while( p )
     557             :         {
     558       10202 :             if( !p->bInvalid )
     559             :             {
     560       10202 :                 SvStorageInfo aInfo( *p );
     561       10202 :                 pList->push_back( aInfo );
     562             :             }
     563       10202 :             p = aIter.Next();
     564             :         }
     565             :     }
     566        1950 : }
     567             : 
     568             : // Open or create a substorage
     569             : 
     570           0 : BaseStorage* Storage::OpenUCBStorage( const OUString& rName, StreamMode m, bool bDirect )
     571             : {
     572             :     OSL_FAIL("Not supported!");
     573           0 :     return OpenStorage( rName, m, bDirect );
     574             : }
     575             : 
     576          62 : BaseStorage* Storage::OpenOLEStorage( const OUString& rName, StreamMode m, bool bDirect )
     577             : {
     578          62 :     return OpenStorage( rName, m, bDirect );
     579             : }
     580             : 
     581         568 : BaseStorage* Storage::OpenStorage( const OUString& rName, StreamMode m, bool bDirect )
     582             : {
     583         568 :     if( !Validate() || !ValidateMode( m ) )
     584           0 :         return new Storage( pIo, NULL, m );
     585         568 :     if( bDirect && !pEntry->bDirect )
     586           0 :         bDirect = false;
     587             : 
     588         568 :     StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
     589         568 :     if( !p )
     590             :     {
     591         134 :         if( !( m & STREAM_NOCREATE ) )
     592             :         {
     593         134 :             bool bTemp = false;
     594             :             // create a new storage
     595         134 :             OUString aNewName = rName;
     596         134 :             if( aNewName.isEmpty() )
     597             :             {
     598           0 :                 aNewName = "Temp Stg " + OUString::number( ++nTmpCount );
     599           0 :                 bTemp = true;
     600             :             }
     601         134 :             p = pIo->pTOC->Create( *pEntry, aNewName, STG_STORAGE );
     602         134 :             if( p )
     603         134 :                 p->bTemp = bTemp;
     604             :         }
     605         134 :         if( !p )
     606           0 :             pIo->SetError( ( m & STREAM_WRITE )
     607           0 :                              ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
     608             :     }
     609         434 :     else if( !ValidateMode( m, p ) )
     610           0 :         p = NULL;
     611         568 :     if( p && p->aEntry.GetType() != STG_STORAGE )
     612             :     {
     613           0 :         pIo->SetError( SVSTREAM_FILE_NOT_FOUND );
     614           0 :         p = NULL;
     615             :     }
     616             : 
     617             :     // Either direct or transacted mode is supported
     618         568 :     if( p && pEntry->nRefCnt == 1 )
     619         568 :         p->bDirect = bDirect;
     620             : 
     621             :     // Dont check direct conflict if opening readonly
     622         568 :     if( p && (m & STREAM_WRITE ))
     623             :     {
     624         394 :         if( p->bDirect != bDirect )
     625           0 :             SetError( SVSTREAM_ACCESS_DENIED );
     626             :     }
     627         568 :     Storage* pStg = new Storage( pIo, p, m );
     628         568 :     pIo->MoveError( *pStg );
     629         568 :     if( m & STREAM_WRITE ) pStg->m_bAutoCommit = true;
     630         568 :     return pStg;
     631             : }
     632             : 
     633             : // Open a stream
     634             : 
     635       11214 : BaseStorageStream* Storage::OpenStream( const OUString& rName, StreamMode m, bool,
     636             :                                         const OString*
     637             : #ifdef DBG_UTIL
     638             :                                         pB
     639             : #endif
     640             : )
     641             : {
     642             :     DBG_ASSERT(!pB, "Encryption not supported");
     643             : 
     644       11214 :     if( !Validate() || !ValidateMode( m ) )
     645           4 :         return new StorageStream( pIo, NULL, m );
     646       11210 :     StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
     647       11210 :     bool bTemp = false;
     648       11210 :     if( !p )
     649             :     {
     650        4216 :         if( !( m & STREAM_NOCREATE ) )
     651             :         {
     652             :             // create a new stream
     653             :             // make a name if the stream is temporary (has no name)
     654        4018 :             OUString aNewName( rName );
     655        4018 :             if( aNewName.isEmpty() )
     656             :             {
     657           0 :                 aNewName = "Temp Strm " + OUString::number( ++nTmpCount );
     658           0 :                 bTemp = true;
     659             :             }
     660        4018 :             p = pIo->pTOC->Create( *pEntry, aNewName, STG_STREAM );
     661             :         }
     662        4216 :         if( !p )
     663         198 :             pIo->SetError( ( m & STREAM_WRITE )
     664         198 :                            ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
     665             :     }
     666        6994 :     else if( !ValidateMode( m, p ) )
     667           0 :         p = NULL;
     668       11210 :     if( p && p->aEntry.GetType() != STG_STREAM )
     669             :     {
     670           0 :         pIo->SetError( SVSTREAM_FILE_NOT_FOUND );
     671           0 :         p = NULL;
     672             :     }
     673       11210 :     if( p )
     674             :     {
     675       11012 :         p->bTemp = bTemp;
     676       11012 :         p->bDirect = pEntry->bDirect;
     677             :     }
     678       11210 :     StorageStream* pStm = new StorageStream( pIo, p, m );
     679       11210 :     if( p && !p->bDirect )
     680       10950 :         pStm->SetAutoCommit( true );
     681       11210 :     pIo->MoveError( *pStm );
     682       11210 :     return pStm;
     683             : }
     684             : 
     685             : // Delete a stream or substorage by setting the temp bit.
     686             : 
     687          28 : bool Storage::Remove( const OUString& rName )
     688             : {
     689          28 :     if( !Validate( true ) )
     690           0 :         return false;
     691          28 :     StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
     692          28 :     if( p )
     693             :     {
     694          28 :         p->Invalidate( true );
     695          28 :         return true;
     696             :     }
     697             :     else
     698             :     {
     699           0 :         SetError( SVSTREAM_FILE_NOT_FOUND );
     700           0 :         return false;
     701             :     }
     702             : }
     703             : 
     704             : // Rename a storage element
     705             : 
     706           0 : bool Storage::Rename( const OUString& rOld, const OUString& rNew )
     707             : {
     708           0 :     if( Validate( true ) )
     709             :     {
     710           0 :         bool b = pIo->pTOC->Rename( *pEntry, rOld, rNew );
     711           0 :         pIo->MoveError( *this );
     712           0 :         return b;
     713             :     }
     714             :     else
     715           0 :         return false;
     716             : }
     717             : 
     718             : // Copy one element
     719             : 
     720        1978 : bool Storage::CopyTo( const OUString& rElem, BaseStorage* pDest, const OUString& rNew )
     721             : {
     722        1978 :     if( !Validate() || !pDest || !pDest->Validate( true ) )
     723           0 :         return false;
     724        1978 :     StgDirEntry* pElem = pIo->pTOC->Find( *pEntry, rElem );
     725        1978 :     if( pElem )
     726             :     {
     727        1978 :         if( pElem->aEntry.GetType() == STG_STORAGE )
     728             :         {
     729             :             // copy the entire storage
     730          62 :             BaseStorage* p1 = OpenStorage( rElem, INTERNAL_MODE );
     731          62 :             BaseStorage* p2 = pDest->OpenOLEStorage( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect );
     732             : 
     733          62 :             if ( p2 )
     734             :             {
     735          62 :                 sal_uLong nTmpErr = p2->GetError();
     736          62 :                 if( !nTmpErr )
     737             :                 {
     738          62 :                     p2->SetClassId( p1->GetClassId() );
     739          62 :                     p1->CopyTo( p2 );
     740          62 :                     SetError( p1->GetError() );
     741             : 
     742          62 :                     nTmpErr = p2->GetError();
     743          62 :                     if( !nTmpErr )
     744          62 :                         p2->Commit();
     745             :                     else
     746           0 :                         pDest->SetError( nTmpErr );
     747             :                 }
     748             :                 else
     749           0 :                     pDest->SetError( nTmpErr );
     750             :             }
     751             : 
     752          62 :             delete p1;
     753          62 :             delete p2;
     754          62 :             return Good() && pDest->Good();
     755             :         }
     756             :         else
     757             :         {
     758             :             // stream copy
     759        1916 :             BaseStorageStream* p1 = OpenStream( rElem, INTERNAL_MODE );
     760        1916 :             BaseStorageStream* p2 = pDest->OpenStream( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pEntry->bDirect );
     761             : 
     762        1916 :             if ( p2 )
     763             :             {
     764        1916 :                 sal_uLong nTmpErr = p2->GetError();
     765        1916 :                 if( !nTmpErr )
     766             :                 {
     767        1916 :                     p1->CopyTo( p2 );
     768        1916 :                     SetError( p1->GetError() );
     769             : 
     770        1916 :                     nTmpErr = p2->GetError();
     771        1916 :                     if( !nTmpErr )
     772        1916 :                         p2->Commit();
     773             :                     else
     774           0 :                         pDest->SetError( nTmpErr );
     775             :                 }
     776             :                 else
     777           0 :                     pDest->SetError( nTmpErr );
     778             :             }
     779             : 
     780        1916 :             delete p1;
     781        1916 :             delete p2;
     782        1916 :             return Good() && pDest->Good();
     783             :         }
     784             :     }
     785           0 :     SetError( SVSTREAM_FILE_NOT_FOUND );
     786           0 :     return false;
     787             : }
     788             : 
     789         222 : bool Storage::CopyTo( BaseStorage* pDest ) const
     790             : {
     791         222 :     if( !Validate() || !pDest || !pDest->Validate( true ) || Equals( *pDest ) )
     792             :     {
     793           2 :         SetError( SVSTREAM_ACCESS_DENIED );
     794           2 :         return false;
     795             :     }
     796         220 :     Storage* pThis = (Storage*) this;
     797         220 :     pDest->SetClassId( GetClassId() );
     798         220 :     pDest->SetDirty();
     799         220 :     SvStorageInfoList aList;
     800         220 :     FillInfoList( &aList );
     801         220 :     bool bRes = true;
     802        2198 :     for( size_t i = 0; i < aList.size() && bRes; i++ )
     803             :     {
     804        1978 :         SvStorageInfo& rInfo = aList[ i ];
     805        1978 :         bRes = pThis->CopyTo( rInfo.GetName(), pDest, rInfo.GetName() );
     806             :     }
     807         220 :     if( !bRes )
     808           0 :         SetError( pDest->GetError() );
     809         220 :     return Good() && pDest->Good();
     810             : }
     811             : 
     812             : // Move one element
     813             : 
     814           0 : bool Storage::MoveTo( const OUString& rElem, BaseStorage* pODest, const OUString& rNew )
     815             : {
     816           0 :     if( !Validate() || !pODest || !pODest->Validate( true ) || Equals( *pODest ) )
     817             :     {
     818           0 :         SetError( SVSTREAM_ACCESS_DENIED );
     819           0 :         return false;
     820             :     }
     821             : 
     822           0 :     StgDirEntry* pElem = pIo->pTOC->Find( *pEntry, rElem );
     823           0 :     if( pElem )
     824             :     {
     825             :         // Simplest case: both storages share the same file
     826             :         bool bRes;
     827           0 :         Storage *pOther = PTR_CAST( Storage, pODest );
     828           0 :         if( pOther && pIo == pOther->pIo && rElem == rNew )
     829             :         {
     830           0 :             Storage *p = static_cast<Storage*>(pODest);
     831           0 :             Storage *pDest = p;
     832             :             // both storages are conventional storages, use implementation dependent code
     833           0 :             if( !pElem->IsContained( pDest->pEntry ) )
     834             :             {
     835             :                 // cyclic move
     836           0 :                 SetError( SVSTREAM_ACCESS_DENIED );
     837           0 :                 return false;
     838             :             }
     839           0 :             bRes = pIo->pTOC->Move( *pEntry, *pDest->pEntry, rNew );
     840           0 :             if( !bRes )
     841             :             {
     842           0 :                 pIo->MoveError( *this );
     843           0 :                 pDest->pIo->MoveError( *pDest );
     844           0 :                 sal_uLong nErr = GetError();
     845           0 :                 if( !nErr )
     846           0 :                     nErr = pDest->GetError();
     847           0 :                 SetError( nErr );
     848           0 :                 pDest->SetError( nErr );
     849             :             }
     850             :         }
     851             :         else
     852             :         {
     853           0 :             bRes = CopyTo( rElem, pODest, rNew );
     854           0 :             if( bRes )
     855           0 :                 bRes = Remove( rElem );
     856             :         }
     857           0 :         if( !bRes )
     858           0 :             SetError( pIo->GetError() );
     859           0 :         return bRes;
     860             :     }
     861           0 :     SetError( SVSTREAM_FILE_NOT_FOUND );
     862           0 :     return false;
     863             : }
     864             : 
     865        3218 : bool Storage::IsStorage( const OUString& rName ) const
     866             : {
     867        3218 :     if( Validate() )
     868             :     {
     869        3218 :         StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
     870        3218 :         if( p )
     871        3218 :             return p->aEntry.GetType() == STG_STORAGE;
     872             :     }
     873           0 :     return false;
     874             : }
     875             : 
     876         424 : bool Storage::IsStream( const OUString& rName ) const
     877             : {
     878         424 :     if( Validate() )
     879             :     {
     880         424 :         StgDirEntry* p = pIo->pTOC->Find( *pEntry, rName );
     881         424 :         if( p )
     882         314 :             return p->aEntry.GetType() == STG_STREAM;
     883             :     }
     884         110 :     return false;
     885             : }
     886             : 
     887        7032 : bool Storage::IsContained( const OUString& rName ) const
     888             : {
     889        7032 :     if( Validate() )
     890        7032 :         return pIo->pTOC->Find( *pEntry, rName ) != NULL;
     891             :     else
     892           0 :         return false;
     893             : }
     894             : 
     895             : // Commit all sub-elements within this storage. If this is
     896             : // the root, commit the FAT, the TOC and the header as well.
     897             : 
     898         826 : bool Storage::Commit()
     899             : {
     900         826 :     bool bRes = true;
     901         826 :     if( !Validate() )
     902           0 :         return false;
     903         826 :     if( !( m_nMode & STREAM_WRITE ) )
     904             :     {
     905           0 :         SetError( SVSTREAM_ACCESS_DENIED );
     906           0 :         return false;
     907             :     }
     908             :     else
     909             :     {
     910             :         // Also commit the sub-streams and Storages
     911         826 :         StgIterator aIter( *pEntry );
     912        7456 :         for( StgDirEntry* p = aIter.First(); p && bRes; p = aIter.Next() )
     913        6630 :             bRes = p->Commit();
     914         826 :         if( bRes && bIsRoot )
     915             :         {
     916         370 :             bRes = pEntry->Commit();
     917         370 :             if( bRes )
     918         370 :                 bRes = pIo->CommitAll();
     919             :         }
     920         826 :         pIo->MoveError( *this );
     921             :     }
     922         826 :     return bRes;
     923             : }
     924             : 
     925           0 : bool Storage::Revert()
     926             : {
     927           0 :     return true;
     928             : }
     929             : 
     930             : ///////////////////////////// OLE Support
     931             : 
     932             : // Set the storage type
     933             : 
     934          62 : void Storage::SetClass( const SvGlobalName & rClass,
     935             :                         sal_uLong nOriginalClipFormat,
     936             :                         const OUString & rUserTypeName )
     937             : {
     938          62 :     if( Validate( true ) )
     939             :     {
     940             :         // set the class name in the root entry
     941          62 :         pEntry->aEntry.SetClassId( (const ClsId&) rClass.GetCLSID() );
     942          62 :         pEntry->SetDirty();
     943             :         // then create the streams
     944          62 :         StgCompObjStream aCompObj( *this, true );
     945          62 :         aCompObj.GetClsId() = (const ClsId&) rClass.GetCLSID();
     946          62 :         aCompObj.GetCbFormat() = nOriginalClipFormat;
     947          62 :         aCompObj.GetUserName() = rUserTypeName;
     948          62 :         if( !aCompObj.Store() )
     949           0 :             SetError( aCompObj.GetError() );
     950             :         else
     951             :         {
     952          62 :             StgOleStream aOle(*this, true);
     953          62 :             if( !aOle.Store() )
     954           0 :                 SetError( aOle.GetError() );
     955          62 :         }
     956             :     }
     957             :     else
     958           0 :         SetError( SVSTREAM_ACCESS_DENIED );
     959          62 : }
     960             : 
     961           0 : void Storage::SetConvertClass( const SvGlobalName & rConvertClass,
     962             :                                sal_uLong nOriginalClipFormat,
     963             :                                const OUString & rUserTypeName )
     964             : {
     965           0 :     if( Validate( true ) )
     966             :     {
     967           0 :         SetClass( rConvertClass, nOriginalClipFormat, rUserTypeName );
     968             :         // plus the convert flag:
     969           0 :         StgOleStream aOle( *this, true );
     970           0 :         aOle.GetFlags() |= 4;
     971           0 :         if( !aOle.Store() )
     972           0 :             SetError( aOle.GetError() );
     973             :     }
     974           0 : }
     975             : 
     976          48 : SvGlobalName Storage::GetClassName()
     977             : {
     978          48 :     StgCompObjStream aCompObj( *this, false );
     979          48 :     if( aCompObj.Load() )
     980          48 :         return SvGlobalName( aCompObj.GetClsId() );
     981           0 :     pIo->ResetError();
     982             : 
     983           0 :     if ( pEntry )
     984           0 :         return SvGlobalName( pEntry->aEntry.GetClassId() );
     985             : 
     986           0 :     return SvGlobalName();
     987             : }
     988             : 
     989           0 : sal_uLong Storage::GetFormat()
     990             : {
     991           0 :     StgCompObjStream aCompObj( *this, false );
     992           0 :     if( aCompObj.Load() )
     993           0 :         return aCompObj.GetCbFormat();
     994           0 :     pIo->ResetError();
     995           0 :     return 0;
     996             : }
     997             : 
     998           0 : OUString Storage::GetUserName()
     999             : {
    1000           0 :     StgCompObjStream aCompObj( *this, false );
    1001           0 :     if( aCompObj.Load() )
    1002           0 :         return aCompObj.GetUserName();
    1003           0 :     pIo->ResetError();
    1004           0 :     return OUString();
    1005             : }
    1006             : 
    1007           0 : bool Storage::ShouldConvert()
    1008             : {
    1009           0 :     StgOleStream aOle( *this, false );
    1010           0 :     if( aOle.Load() )
    1011           0 :         return ( aOle.GetFlags() & 4 ) != 0;
    1012             :     else
    1013             :     {
    1014           0 :         pIo->ResetError();
    1015           0 :         return false;
    1016           0 :     }
    1017             : }
    1018             : 
    1019           8 : bool Storage::ValidateFAT()
    1020             : {
    1021           8 :     Link aLink = StgIo::GetErrorLink();
    1022           8 :     ErrCode nErr = pIo->ValidateFATs();
    1023           8 :     StgIo::SetErrorLink( aLink );
    1024           8 :     return nErr == ERRCODE_NONE;
    1025             : }
    1026             : 
    1027         220 : void Storage::SetDirty()
    1028             : {
    1029         220 :     if ( pEntry )
    1030         220 :         pEntry->SetDirty();
    1031         220 : }
    1032             : 
    1033         282 : void Storage::SetClassId( const ClsId& rId )
    1034             : {
    1035         282 :     if ( pEntry )
    1036         282 :         pEntry->aEntry.SetClassId( rId );
    1037         282 : }
    1038             : 
    1039         282 : const ClsId& Storage::GetClassId() const
    1040             : {
    1041         282 :     if ( pEntry )
    1042         282 :         return pEntry->aEntry.GetClassId();
    1043             : 
    1044             :     static ClsId aDummyId = {0,0,0,{0,0,0,0,0,0,0,0}};
    1045           0 :     return aDummyId;
    1046             : }
    1047             : 
    1048           0 : const SvStream* Storage::GetSvStream() const
    1049             : {
    1050           0 :     return GetSvStream_Impl();
    1051             : }
    1052             : 
    1053       29982 : bool Storage::Validate( bool bValidate ) const
    1054             : {
    1055       29982 :     bool bRet = Validate_Impl( bValidate );
    1056       29982 :     if ( !bRet )
    1057         124 :         SetError( SVSTREAM_ACCESS_DENIED );
    1058       29982 :     return bRet;
    1059             : }
    1060             : 
    1061       11778 : bool Storage::ValidateMode( StreamMode nMode ) const
    1062             : {
    1063       11778 :     bool bRet = ValidateMode_Impl( nMode );
    1064       11778 :     if ( !bRet )
    1065           0 :         SetError( SVSTREAM_ACCESS_DENIED );
    1066       11778 :     return bRet;
    1067             : }
    1068             : 
    1069        7428 : bool Storage::ValidateMode( StreamMode nMode, StgDirEntry* p ) const
    1070             : {
    1071        7428 :     bool bRet = ValidateMode_Impl( nMode, p );
    1072        7428 :     if ( !bRet )
    1073           0 :         SetError( SVSTREAM_ACCESS_DENIED );
    1074        7428 :     return bRet;
    1075             : }
    1076             : 
    1077         220 : bool Storage::Equals( const BaseStorage& rStorage ) const
    1078             : {
    1079         220 :     const Storage* pOther = PTR_CAST( Storage, &rStorage );
    1080         220 :     return pOther && ( pOther->pEntry == pEntry );
    1081             : }
    1082             : 
    1083             : 
    1084             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10