LCOV - code coverage report
Current view: top level - package/source/xstor - owriteablestream.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 794 1576 50.4 %
Date: 2014-11-03 Functions: 64 100 64.0 %
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             : #include <com/sun/star/uno/XComponentContext.hpp>
      21             : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
      22             : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
      23             : #include <com/sun/star/lang/DisposedException.hpp>
      24             : #include <com/sun/star/lang/XUnoTunnel.hpp>
      25             : #include <com/sun/star/lang/XTypeProvider.hpp>
      26             : #include <com/sun/star/logging/DocumentIOLogRing.hpp>
      27             : #include <com/sun/star/io/TempFile.hpp>
      28             : #include <com/sun/star/io/XInputStream.hpp>
      29             : #include <com/sun/star/io/IOException.hpp>
      30             : #include <com/sun/star/embed/ElementModes.hpp>
      31             : #include <com/sun/star/embed/StorageFormats.hpp>
      32             : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
      33             : #include <cppuhelper/typeprovider.hxx>
      34             : #include <cppuhelper/exc_hlp.hxx>
      35             : #include <osl/diagnose.h>
      36             : 
      37             : #include <comphelper/processfactory.hxx>
      38             : #include <comphelper/storagehelper.hxx>
      39             : #include <comphelper/ofopxmlhelper.hxx>
      40             : 
      41             : #include <rtl/digest.h>
      42             : #include <rtl/instance.hxx>
      43             : 
      44             : #include <PackageConstants.hxx>
      45             : #include <mutexholder.hxx>
      46             : 
      47             : #include "selfterminatefilestream.hxx"
      48             : #include "owriteablestream.hxx"
      49             : #include "oseekinstream.hxx"
      50             : #include "xstorage.hxx"
      51             : 
      52             : // since the copying uses 32000 blocks usually, it makes sense to have a smaller size
      53             : #define MAX_STORCACHE_SIZE 30000
      54             : 
      55             : using namespace ::com::sun::star;
      56             : 
      57             : namespace package
      58             : {
      59             : 
      60           2 : bool PackageEncryptionDatasEqual( const ::comphelper::SequenceAsHashMap& aHash1, const ::comphelper::SequenceAsHashMap& aHash2 )
      61             : {
      62           2 :     bool bResult = ( aHash1.size() && aHash1.size() == aHash2.size() );
      63          24 :     for ( ::comphelper::SequenceAsHashMap::const_iterator aIter = aHash1.begin();
      64          24 :           bResult && aIter != aHash1.end();
      65             :           ++aIter )
      66             :     {
      67           6 :         uno::Sequence< sal_Int8 > aKey1;
      68           6 :         bResult = ( ( aIter->second >>= aKey1 ) && aKey1.getLength() );
      69           6 :         if ( bResult )
      70             :         {
      71           6 :             uno::Sequence< sal_Int8 > aKey2 = aHash2.getUnpackedValueOrDefault( aIter->first, uno::Sequence< sal_Int8 >() );
      72           6 :             bResult = ( aKey1.getLength() == aKey2.getLength() );
      73         150 :             for ( sal_Int32 nInd = 0; bResult && nInd < aKey1.getLength(); nInd++ )
      74         150 :                 bResult = ( aKey1[nInd] == aKey2[nInd] );
      75             :         }
      76           6 :     }
      77             : 
      78           2 :     return bResult;
      79             : }
      80             : 
      81             : } // namespace package
      82             : 
      83             : namespace
      84             : {
      85             : 
      86          36 : void SetEncryptionKeyProperty_Impl( const uno::Reference< beans::XPropertySet >& xPropertySet,
      87             :                                     const uno::Sequence< beans::NamedValue >& aKey )
      88             : {
      89             :     SAL_WARN_IF( !xPropertySet.is(), "package.xstor", "No property set is provided!" );
      90          36 :     if ( !xPropertySet.is() )
      91           0 :         throw uno::RuntimeException();
      92             : 
      93             :     try {
      94          36 :         xPropertySet->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY, uno::makeAny( aKey ) );
      95             :     }
      96           0 :     catch ( const uno::Exception& rException )
      97             :     {
      98             :         SAL_INFO("package.xstor", rException.Message);
      99             :         SAL_INFO("package.xstor", "Can't set encryption");
     100             :         SAL_WARN( "package.xstor", "Can't write encryption related properties!" );
     101           0 :         throw io::IOException(); // TODO
     102             :     }
     103          36 : }
     104             : 
     105         116 : uno::Any GetEncryptionKeyProperty_Impl( const uno::Reference< beans::XPropertySet >& xPropertySet )
     106             : {
     107             :     SAL_WARN_IF( !xPropertySet.is(), "package.xstor", "No property set is provided!" );
     108         116 :     if ( !xPropertySet.is() )
     109           0 :         throw uno::RuntimeException();
     110             : 
     111             :     try {
     112         116 :         return xPropertySet->getPropertyValue(STORAGE_ENCRYPTION_KEYS_PROPERTY);
     113             :     }
     114           0 :     catch ( const uno::Exception& rException )
     115             :     {
     116             :         SAL_INFO("package.xstor", rException.Message);
     117             :         SAL_INFO("package.xstor", "Can't get encryption property");
     118             : 
     119             :         SAL_WARN( "package.xstor", "Can't get encryption related properties!" );
     120           0 :         throw io::IOException(); // TODO
     121             :     }
     122             : }
     123             : 
     124           0 : bool SequencesEqual( const uno::Sequence< sal_Int8 >& aSequence1, const uno::Sequence< sal_Int8 >& aSequence2 )
     125             : {
     126           0 :     if ( aSequence1.getLength() != aSequence2.getLength() )
     127           0 :         return false;
     128             : 
     129           0 :     for ( sal_Int32 nInd = 0; nInd < aSequence1.getLength(); nInd++ )
     130           0 :         if ( aSequence1[nInd] != aSequence2[nInd] )
     131           0 :             return false;
     132             : 
     133           0 :     return true;
     134             : }
     135             : 
     136           0 : bool SequencesEqual( const uno::Sequence< beans::NamedValue >& aSequence1, const uno::Sequence< beans::NamedValue >& aSequence2 )
     137             : {
     138           0 :     if ( aSequence1.getLength() != aSequence2.getLength() )
     139           0 :         return false;
     140             : 
     141           0 :     for ( sal_Int32 nInd = 0; nInd < aSequence1.getLength(); nInd++ )
     142             :     {
     143           0 :         bool bHasMember = false;
     144           0 :         uno::Sequence< sal_Int8 > aMember1;
     145           0 :         sal_Int32 nMember1 = 0;
     146           0 :         if ( ( aSequence1[nInd].Value >>= aMember1 ) )
     147             :         {
     148           0 :             for ( sal_Int32 nInd2 = 0; nInd2 < aSequence2.getLength(); nInd2++ )
     149             :             {
     150           0 :                 if ( aSequence1[nInd].Name.equals( aSequence2[nInd2].Name ) )
     151             :                 {
     152           0 :                     bHasMember = true;
     153             : 
     154           0 :                     uno::Sequence< sal_Int8 > aMember2;
     155           0 :                     if ( !( aSequence2[nInd2].Value >>= aMember2 ) || !SequencesEqual( aMember1, aMember2 ) )
     156           0 :                         return false;
     157             :                 }
     158             :             }
     159             :         }
     160           0 :         else if ( ( aSequence1[nInd].Value >>= nMember1 ) )
     161             :         {
     162           0 :             for ( sal_Int32 nInd2 = 0; nInd2 < aSequence2.getLength(); nInd2++ )
     163             :             {
     164           0 :                 if ( aSequence1[nInd].Name.equals( aSequence2[nInd2].Name ) )
     165             :                 {
     166           0 :                     bHasMember = true;
     167             : 
     168           0 :                     sal_Int32 nMember2 = 0;
     169           0 :                     if ( !( aSequence2[nInd2].Value >>= nMember2 ) || nMember1 != nMember2 )
     170           0 :                         return false;
     171             :                 }
     172             :             }
     173             :         }
     174             :         else
     175           0 :             return false;
     176             : 
     177           0 :         if ( !bHasMember )
     178           0 :             return false;
     179           0 :     }
     180             : 
     181           0 :     return true;
     182             : }
     183             : 
     184        1010 : bool KillFile( const OUString& aURL, const uno::Reference< uno::XComponentContext >& xContext )
     185             : {
     186        1010 :     if ( !xContext.is() )
     187           0 :         return false;
     188             : 
     189        1010 :     bool bRet = false;
     190             : 
     191             :     try
     192             :     {
     193        1010 :         uno::Reference < ucb::XSimpleFileAccess3 > xAccess( ucb::SimpleFileAccess::create( xContext ) );
     194             : 
     195        1010 :         xAccess->kill( aURL );
     196        1010 :         bRet = true;
     197             :     }
     198           0 :     catch( const uno::Exception& rException )
     199             :     {
     200             :         SAL_INFO("package.xstor", rException.Message);
     201             :         SAL_INFO("package.xstor", "Quiet exception");
     202             :     }
     203             : 
     204        1010 :     return bRet;
     205             : }
     206             : 
     207        1528 : OUString GetNewTempFileURL( const uno::Reference< uno::XComponentContext > xContext )
     208             : {
     209        1528 :     OUString aTempURL;
     210             : 
     211             :     uno::Reference < beans::XPropertySet > xTempFile(
     212             :             io::TempFile::create(xContext),
     213        3056 :             uno::UNO_QUERY_THROW );
     214             : 
     215             :     try {
     216        1528 :         xTempFile->setPropertyValue( "RemoveFile", uno::makeAny( sal_False ) );
     217        1528 :         uno::Any aUrl = xTempFile->getPropertyValue( "Uri" );
     218        1528 :         aUrl >>= aTempURL;
     219             :     }
     220           0 :     catch ( const uno::Exception& rException )
     221             :     {
     222             :         SAL_INFO("package.xstor", rException.Message);
     223             :         SAL_INFO("package.xstor", "Quiet exception");
     224             :     }
     225             : 
     226        1528 :     if ( aTempURL.isEmpty() )
     227           0 :         throw uno::RuntimeException(); // TODO: can not create tempfile
     228             : 
     229        3056 :     return aTempURL;
     230             : }
     231             : 
     232       50132 : uno::Reference< io::XStream > CreateMemoryStream( const uno::Reference< uno::XComponentContext >& xContext )
     233             : {
     234             :     return uno::Reference< io::XStream >(
     235      100264 :         xContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.MemoryStream", xContext),
     236      100258 :         uno::UNO_QUERY_THROW);
     237             : }
     238             : 
     239             : } // anonymous namespace
     240             : 
     241       89494 : OWriteStream_Impl::OWriteStream_Impl( OStorage_Impl* pParent,
     242             :                                       const uno::Reference< packages::XDataSinkEncrSupport >& xPackageStream,
     243             :                                       const uno::Reference< lang::XSingleServiceFactory >& xPackage,
     244             :                                       const uno::Reference< uno::XComponentContext >& xContext,
     245             :                                       bool bForceEncrypted,
     246             :                                       sal_Int32 nStorageType,
     247             :                                       bool bDefaultCompress,
     248             :                                       const uno::Reference< io::XInputStream >& xRelInfoStream )
     249             : : m_pAntiImpl( NULL )
     250             : , m_bHasDataToFlush( false )
     251             : , m_bFlushed( false )
     252             : , m_xPackageStream( xPackageStream )
     253             : , m_xContext( xContext )
     254             : , m_pParent( pParent )
     255             : , m_bForceEncrypted( bForceEncrypted )
     256       89494 : , m_bUseCommonEncryption( !bForceEncrypted && nStorageType == embed::StorageFormats::PACKAGE )
     257             : , m_bHasCachedEncryptionData( false )
     258       89494 : , m_bCompressedSetExplicit( !bDefaultCompress )
     259             : , m_xPackage( xPackage )
     260             : , m_bHasInsertedStreamOptimization( false )
     261             : , m_nStorageType( nStorageType )
     262             : , m_xOrigRelInfoStream( xRelInfoStream )
     263             : , m_bOrigRelInfoBroken( false )
     264             : , m_nRelInfoStatus( RELINFO_NO_INIT )
     265      268482 : , m_nRelId( 1 )
     266             : {
     267             :     SAL_WARN_IF( !xPackageStream.is(), "package.xstor", "No package stream is provided!" );
     268             :     SAL_WARN_IF( !xPackage.is(), "package.xstor", "No package component is provided!" );
     269             :     SAL_WARN_IF( !m_xContext.is(), "package.xstor", "No package stream is provided!" );
     270             :     OSL_ENSURE( pParent, "No parent storage is provided!\n" );
     271             :     OSL_ENSURE( m_nStorageType == embed::StorageFormats::OFOPXML || !m_xOrigRelInfoStream.is(), "The Relations info makes sence only for OFOPXML format!\n" );
     272       89494 : }
     273             : 
     274      178940 : OWriteStream_Impl::~OWriteStream_Impl()
     275             : {
     276       89470 :     DisposeWrappers();
     277             : 
     278       89470 :     if ( !m_aTempURL.isEmpty() )
     279             :     {
     280        1010 :         KillFile( m_aTempURL, comphelper::getProcessComponentContext() );
     281        1010 :         m_aTempURL = OUString();
     282             :     }
     283             : 
     284       89470 :     CleanCacheStream();
     285       89470 : }
     286             : 
     287       89922 : void OWriteStream_Impl::CleanCacheStream()
     288             : {
     289       89922 :     if ( m_xCacheStream.is() )
     290             :     {
     291             :         try
     292             :         {
     293       26038 :             uno::Reference< io::XInputStream > xInputCache = m_xCacheStream->getInputStream();
     294       26038 :             if ( xInputCache.is() )
     295       26038 :                 xInputCache->closeInput();
     296             :         }
     297           0 :         catch( const uno::Exception& )
     298             :         {}
     299             : 
     300             :         try
     301             :         {
     302       26038 :             uno::Reference< io::XOutputStream > xOutputCache = m_xCacheStream->getOutputStream();
     303       26038 :             if ( xOutputCache.is() )
     304       26038 :                 xOutputCache->closeOutput();
     305             :         }
     306           0 :         catch( const uno::Exception& )
     307             :         {}
     308             : 
     309       26038 :         m_xCacheStream = uno::Reference< io::XStream >();
     310       26038 :         m_xCacheSeek = uno::Reference< io::XSeekable >();
     311             :     }
     312       89922 : }
     313             : 
     314           4 : void OWriteStream_Impl::AddLog( const OUString& aMessage )
     315             : {
     316           4 :     if ( !m_xLogRing.is() )
     317             :     {
     318             :         try
     319             :         {
     320           2 :             uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
     321           2 :             m_xLogRing = logging::DocumentIOLogRing::get(xContext);
     322             :         }
     323           0 :         catch( const uno::Exception& )
     324             :         {
     325             :             // No log
     326             :         }
     327             :     }
     328             : 
     329           4 :     if ( m_xLogRing.is() )
     330           4 :         m_xLogRing->logString( aMessage );
     331           4 : }
     332             : 
     333       20994 : void OWriteStream_Impl::InsertIntoPackageFolder( const OUString& aName,
     334             :                                                   const uno::Reference< container::XNameContainer >& xParentPackageFolder )
     335             : {
     336       20994 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
     337             : 
     338             :     SAL_WARN_IF( !m_bFlushed, "package.xstor", "This method must not be called for nonflushed streams!" );
     339       20994 :     if ( m_bFlushed )
     340             :     {
     341             :         SAL_WARN_IF( !m_xPackageStream.is(), "package.xstor", "An inserted stream is incomplete!\n" );
     342       20994 :         uno::Reference< lang::XUnoTunnel > xTunnel( m_xPackageStream, uno::UNO_QUERY );
     343       20994 :         if ( !xTunnel.is() )
     344           0 :             throw uno::RuntimeException(); // TODO
     345             : 
     346       20994 :         xParentPackageFolder->insertByName( aName, uno::makeAny( xTunnel ) );
     347             : 
     348       20994 :         m_bFlushed = false;
     349       20994 :         m_bHasInsertedStreamOptimization = false;
     350       20994 :     }
     351       20994 : }
     352      103080 : bool OWriteStream_Impl::IsEncrypted()
     353             : {
     354      103080 :     if ( m_nStorageType != embed::StorageFormats::PACKAGE )
     355       88840 :         return false;
     356             : 
     357       14240 :     if ( m_bForceEncrypted || m_bHasCachedEncryptionData )
     358           2 :         return true;
     359             : 
     360       14238 :     if ( !m_aTempURL.isEmpty() || m_xCacheStream.is() )
     361          82 :         return false;
     362             : 
     363       14156 :     GetStreamProperties();
     364             : 
     365             :     // the following value can not be cached since it can change after root commit
     366       14156 :     bool bWasEncr = false;
     367       14156 :     uno::Reference< beans::XPropertySet > xPropSet( m_xPackageStream, uno::UNO_QUERY );
     368       14156 :     if ( xPropSet.is() )
     369             :     {
     370       14156 :         uno::Any aValue = xPropSet->getPropertyValue("WasEncrypted");
     371       14156 :         if ( !( aValue >>= bWasEncr ) )
     372             :         {
     373             :             SAL_WARN( "package.xstor", "The property WasEncrypted has wrong type!" );
     374       14156 :         }
     375             :     }
     376             : 
     377       14156 :     bool bToBeEncr = false;
     378       70780 :     for ( sal_Int32 nInd = 0; nInd < m_aProps.getLength(); nInd++ )
     379             :     {
     380       56624 :         if ( m_aProps[nInd].Name == "Encrypted" )
     381             :         {
     382       14156 :             if ( !( m_aProps[nInd].Value >>= bToBeEncr ) )
     383             :             {
     384             :                 SAL_WARN( "package.xstor", "The property has wrong type!" );
     385             :             }
     386             :         }
     387             :     }
     388             : 
     389             :     // since a new key set to the package stream it should not be removed except the case when
     390             :     // the stream becomes nonencrypted
     391       28312 :     uno::Sequence< beans::NamedValue > aKey;
     392       14156 :     if ( bToBeEncr )
     393         116 :         GetEncryptionKeyProperty_Impl( xPropSet ) >>= aKey;
     394             : 
     395             :     // If the properties must be investigated the stream is either
     396             :     // was never changed or was changed, the parent was commited
     397             :     // and the stream was closed.
     398             :     // That means that if it is intended to use common storage key
     399             :     // it is already has no encryption but is marked to be stored
     400             :     // encrypted and the key is empty.
     401       14156 :     if ( !bWasEncr && bToBeEncr && !aKey.getLength() )
     402             :     {
     403             :         // the stream is intended to use common storage password
     404          40 :         m_bUseCommonEncryption = true;
     405          40 :         return false;
     406             :     }
     407             :     else
     408       28272 :         return bToBeEncr;
     409             : }
     410             : 
     411           0 : void OWriteStream_Impl::SetDecrypted()
     412             : {
     413             :     SAL_WARN_IF( m_nStorageType != embed::StorageFormats::PACKAGE, "package.xstor", "The encryption is supported only for package storages!" );
     414           0 :     if ( m_nStorageType != embed::StorageFormats::PACKAGE )
     415           0 :         throw uno::RuntimeException();
     416             : 
     417           0 :     GetStreamProperties();
     418             : 
     419             :     // let the stream be modified
     420           0 :     FillTempGetFileName();
     421           0 :     m_bHasDataToFlush = true;
     422             : 
     423             :     // remove encryption
     424           0 :     m_bForceEncrypted = false;
     425           0 :     m_bHasCachedEncryptionData = false;
     426           0 :     m_aEncryptionData.clear();
     427             : 
     428           0 :     for ( sal_Int32 nInd = 0; nInd < m_aProps.getLength(); nInd++ )
     429             :     {
     430           0 :         if ( m_aProps[nInd].Name == "Encrypted" )
     431           0 :             m_aProps[nInd].Value <<= false;
     432             :     }
     433           0 : }
     434             : 
     435           0 : void OWriteStream_Impl::SetEncrypted( const ::comphelper::SequenceAsHashMap& aEncryptionData )
     436             : {
     437             :     SAL_WARN_IF( m_nStorageType != embed::StorageFormats::PACKAGE, "package.xstor", "The encryption is supported only for package storages!" );
     438           0 :     if ( m_nStorageType != embed::StorageFormats::PACKAGE )
     439           0 :         throw uno::RuntimeException();
     440             : 
     441           0 :     if ( !aEncryptionData.size() )
     442           0 :         throw uno::RuntimeException();
     443             : 
     444           0 :     GetStreamProperties();
     445             : 
     446             :     // let the stream be modified
     447           0 :     FillTempGetFileName();
     448           0 :     m_bHasDataToFlush = true;
     449             : 
     450             :     // introduce encryption info
     451           0 :     for ( sal_Int32 nInd = 0; nInd < m_aProps.getLength(); nInd++ )
     452             :     {
     453           0 :         if ( m_aProps[nInd].Name == "Encrypted" )
     454           0 :             m_aProps[nInd].Value <<= true;
     455             :     }
     456             : 
     457           0 :     m_bUseCommonEncryption = false; // very important to set it to false
     458             : 
     459           0 :     m_bHasCachedEncryptionData = true;
     460           0 :     m_aEncryptionData = aEncryptionData;
     461           0 : }
     462             : 
     463       89470 : void OWriteStream_Impl::DisposeWrappers()
     464             : {
     465       89470 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
     466       89470 :     if ( m_pAntiImpl )
     467             :     {
     468             :         try {
     469          12 :             m_pAntiImpl->dispose();
     470             :         }
     471           0 :         catch ( const uno::RuntimeException& rRuntimeException )
     472             :         {
     473           0 :             AddLog( rRuntimeException.Message );
     474           0 :             AddLog( "Quiet exception" );
     475             :         }
     476             : 
     477          12 :         m_pAntiImpl = NULL;
     478             :     }
     479       89470 :     m_pParent = NULL;
     480             : 
     481       89470 :     if ( !m_aInputStreamsList.empty() )
     482             :     {
     483         924 :         for ( InputStreamsList_Impl::iterator pStreamIter = m_aInputStreamsList.begin();
     484         616 :               pStreamIter != m_aInputStreamsList.end(); ++pStreamIter )
     485             :         {
     486         154 :             if ( (*pStreamIter) )
     487             :             {
     488         154 :                 (*pStreamIter)->InternalDispose();
     489         154 :                 (*pStreamIter) = NULL;
     490             :             }
     491             :         }
     492             : 
     493         154 :         m_aInputStreamsList.clear();
     494       89470 :     }
     495       89470 : }
     496             : 
     497         452 : OUString OWriteStream_Impl::GetFilledTempFileIfNo( const uno::Reference< io::XInputStream >& xStream )
     498             : {
     499         452 :     if ( !m_aTempURL.getLength() )
     500             :     {
     501         452 :         OUString aTempURL = GetNewTempFileURL( m_xContext );
     502             : 
     503             :         try {
     504         452 :             if ( !aTempURL.isEmpty() && xStream.is() )
     505             :             {
     506         452 :                 uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess( ucb::SimpleFileAccess::create( ::comphelper::getProcessComponentContext() ) );
     507             : 
     508         904 :                 uno::Reference< io::XOutputStream > xTempOutStream = xTempAccess->openFileWrite( aTempURL );
     509         452 :                 if ( xTempOutStream.is() )
     510             :                 {
     511             :                     // the current position of the original stream should be still OK, copy further
     512         452 :                     ::comphelper::OStorageHelper::CopyInputToOutput( xStream, xTempOutStream );
     513         452 :                     xTempOutStream->closeOutput();
     514         452 :                     xTempOutStream = uno::Reference< io::XOutputStream >();
     515             :                 }
     516             :                 else
     517         452 :                     throw io::IOException(); // TODO:
     518             :             }
     519             :         }
     520           0 :         catch( const packages::WrongPasswordException& rWrongPasswordException )
     521             :         {
     522           0 :             AddLog( rWrongPasswordException.Message );
     523           0 :             AddLog( "Rethrow" );
     524             : 
     525           0 :             KillFile( aTempURL, comphelper::getProcessComponentContext() );
     526           0 :             throw;
     527             :         }
     528           0 :         catch( const uno::Exception& rException )
     529             :         {
     530           0 :             AddLog( rException.Message );
     531           0 :             AddLog( "Rethrow" );
     532             : 
     533           0 :             KillFile( aTempURL, comphelper::getProcessComponentContext() );
     534           0 :         throw;
     535             :         }
     536             : 
     537         452 :         if ( !aTempURL.isEmpty() )
     538         452 :             CleanCacheStream();
     539             : 
     540         452 :         m_aTempURL = aTempURL;
     541             :     }
     542             : 
     543         452 :     return m_aTempURL;
     544             : }
     545             : 
     546       40008 : OUString OWriteStream_Impl::FillTempGetFileName()
     547             : {
     548             :     // should try to create cache first, if the amount of contents is too big, the temp file should be taken
     549       40008 :     if ( !m_xCacheStream.is() && m_aTempURL.isEmpty() )
     550             :     {
     551       40008 :         uno::Reference< io::XInputStream > xOrigStream = m_xPackageStream->getDataStream();
     552       40008 :         if ( !xOrigStream.is() )
     553             :         {
     554             :             // in case of new inserted package stream it is possible that input stream still was not set
     555       13078 :             uno::Reference< io::XStream > xCacheStream = CreateMemoryStream( m_xContext );
     556             :             SAL_WARN_IF( !xCacheStream.is(), "package.xstor", "If the stream can not be created an exception must be thrown!" );
     557       13078 :             m_xCacheSeek.set( xCacheStream, uno::UNO_QUERY_THROW );
     558       13078 :             m_xCacheStream = xCacheStream;
     559             :         }
     560             :         else
     561             :         {
     562       26930 :             sal_Int32 nRead = 0;
     563       26930 :             uno::Sequence< sal_Int8 > aData( MAX_STORCACHE_SIZE + 1 );
     564       26930 :             nRead = xOrigStream->readBytes( aData, MAX_STORCACHE_SIZE + 1 );
     565       26930 :             if ( aData.getLength() > nRead )
     566           0 :                 aData.realloc( nRead );
     567             : 
     568       26930 :             if ( nRead <= MAX_STORCACHE_SIZE )
     569             :             {
     570       25854 :                 uno::Reference< io::XStream > xCacheStream = CreateMemoryStream( m_xContext );
     571             :                 SAL_WARN_IF( !xCacheStream.is(), "package.xstor", "If the stream can not be created an exception must be thrown!" );
     572             : 
     573       25852 :                 if ( nRead )
     574             :                 {
     575       25816 :                     uno::Reference< io::XOutputStream > xOutStream( xCacheStream->getOutputStream(), uno::UNO_SET_THROW );
     576       25816 :                     xOutStream->writeBytes( aData );
     577             :                 }
     578       25852 :                 m_xCacheSeek.set( xCacheStream, uno::UNO_QUERY_THROW );
     579       25852 :                 m_xCacheStream = xCacheStream;
     580       25852 :                 m_xCacheSeek->seek( 0 );
     581             :             }
     582        1076 :             else if ( m_aTempURL.isEmpty() )
     583             :             {
     584        1076 :                 m_aTempURL = GetNewTempFileURL( m_xContext );
     585             : 
     586             :                 try {
     587        1076 :                     if ( !m_aTempURL.isEmpty() )
     588             :                     {
     589        1076 :                         uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess( ucb::SimpleFileAccess::create( ::comphelper::getProcessComponentContext() ) );
     590             : 
     591        2152 :                         uno::Reference< io::XOutputStream > xTempOutStream = xTempAccess->openFileWrite( m_aTempURL );
     592        1076 :                         if ( xTempOutStream.is() )
     593             :                         {
     594             :                             // copy stream contents to the file
     595        1076 :                             xTempOutStream->writeBytes( aData );
     596             : 
     597             :                             // the current position of the original stream should be still OK, copy further
     598        1076 :                             ::comphelper::OStorageHelper::CopyInputToOutput( xOrigStream, xTempOutStream );
     599        1076 :                             xTempOutStream->closeOutput();
     600        1076 :                             xTempOutStream = uno::Reference< io::XOutputStream >();
     601             :                         }
     602             :                         else
     603        1076 :                             throw io::IOException(); // TODO:
     604             :                     }
     605             :                 }
     606           0 :                 catch( const packages::WrongPasswordException& )
     607             :                 {
     608           0 :                     KillFile( m_aTempURL, comphelper::getProcessComponentContext() );
     609           0 :                     m_aTempURL = OUString();
     610             : 
     611           0 :                     throw;
     612             :                 }
     613           0 :                 catch( const uno::Exception& )
     614             :                 {
     615           0 :                     KillFile( m_aTempURL, comphelper::getProcessComponentContext() );
     616           0 :                     m_aTempURL = OUString();
     617             :                 }
     618       26930 :             }
     619       40008 :         }
     620             :     }
     621             : 
     622       40006 :     return m_aTempURL;
     623             : }
     624             : 
     625       14920 : uno::Reference< io::XStream > OWriteStream_Impl::GetTempFileAsStream()
     626             : {
     627       14920 :     uno::Reference< io::XStream > xTempStream;
     628             : 
     629       14920 :     if ( !m_xCacheStream.is() )
     630             :     {
     631       14914 :         if ( m_aTempURL.isEmpty() )
     632       14462 :             m_aTempURL = FillTempGetFileName();
     633             : 
     634       14912 :         if ( !m_aTempURL.isEmpty() )
     635             :         {
     636             :             // the temporary file is not used if the cache is used
     637         522 :             uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess( ucb::SimpleFileAccess::create( ::comphelper::getProcessComponentContext() ) );
     638             : 
     639             :             try
     640             :             {
     641         522 :                 xTempStream = xTempAccess->openFileReadWrite( m_aTempURL );
     642             :             }
     643           0 :             catch( const uno::Exception& rException )
     644             :             {
     645           0 :                 AddLog( rException.Message );
     646           0 :                 AddLog( "Quiet exception" );
     647         522 :             }
     648             :         }
     649             :     }
     650             : 
     651       14918 :     if ( m_xCacheStream.is() )
     652       14396 :         xTempStream = m_xCacheStream;
     653             : 
     654             :     // the method must always return a stream
     655             :     // in case the stream can not be open
     656             :     // an exception should be thrown
     657       14918 :     if ( !xTempStream.is() )
     658           0 :         throw io::IOException(); //TODO:
     659             : 
     660       14918 :     return xTempStream;
     661             : }
     662             : 
     663       34658 : uno::Reference< io::XInputStream > OWriteStream_Impl::GetTempFileAsInputStream()
     664             : {
     665       34658 :     uno::Reference< io::XInputStream > xInputStream;
     666             : 
     667       34658 :     if ( !m_xCacheStream.is() )
     668             :     {
     669       25546 :         if ( m_aTempURL.isEmpty() )
     670       25546 :             m_aTempURL = FillTempGetFileName();
     671             : 
     672       25546 :         if ( !m_aTempURL.isEmpty() )
     673             :         {
     674             :             // the temporary file is not used if the cache is used
     675        1006 :             uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess( ucb::SimpleFileAccess::create( ::comphelper::getProcessComponentContext() ) );
     676             : 
     677             :             try
     678             :             {
     679        1006 :                 xInputStream = xTempAccess->openFileRead( m_aTempURL );
     680             :             }
     681           0 :             catch( const uno::Exception& rException )
     682             :             {
     683           0 :                 AddLog( rException.Message );
     684           0 :                 AddLog( "Quiet exception" );
     685        1006 :             }
     686             :         }
     687             :     }
     688             : 
     689       34658 :     if ( m_xCacheStream.is() )
     690       33652 :         xInputStream = m_xCacheStream->getInputStream();
     691             : 
     692             :     // the method must always return a stream
     693             :     // in case the stream can not be open
     694             :     // an exception should be thrown
     695       34658 :     if ( !xInputStream.is() )
     696           0 :         throw io::IOException(); // TODO:
     697             : 
     698       34658 :     return xInputStream;
     699             : }
     700             : 
     701          32 : void OWriteStream_Impl::InsertStreamDirectly( const uno::Reference< io::XInputStream >& xInStream,
     702             :                                               const uno::Sequence< beans::PropertyValue >& aProps )
     703             : {
     704          32 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
     705             : 
     706             :     // this call can be made only during parent storage commit
     707             :     // the  parent storage is responsible for the correct handling
     708             :     // of deleted and renamed contents
     709             : 
     710             :     SAL_WARN_IF( !m_xPackageStream.is(), "package.xstor", "No package stream is set!" );
     711             : 
     712          32 :     if ( m_bHasDataToFlush )
     713           0 :         throw io::IOException();
     714             : 
     715             :     OSL_ENSURE( m_aTempURL.isEmpty() && !m_xCacheStream.is(), "The temporary must not exist!\n" );
     716             : 
     717             :     // use new file as current persistent representation
     718             :     // the new file will be removed after it's stream is closed
     719          32 :     m_xPackageStream->setDataStream( xInStream );
     720             : 
     721             :     // copy properties to the package stream
     722          64 :     uno::Reference< beans::XPropertySet > xPropertySet( m_xPackageStream, uno::UNO_QUERY );
     723          32 :     if ( !xPropertySet.is() )
     724           0 :         throw uno::RuntimeException();
     725             : 
     726             :     // The storage-package communication has a problem
     727             :     // the storage caches properties, thus if the package changes one of them itself
     728             :     // the storage does not know about it
     729             : 
     730             :     // Depending from MediaType value the package can change the compressed property itself
     731             :     // Thus if Compressed property is provided it must be set as the latest one
     732          32 :     bool bCompressedIsSet = false;
     733          32 :     bool bCompressed = false;
     734          64 :     OUString aComprPropName( "Compressed" );
     735          64 :     OUString aMedTypePropName( "MediaType" );
     736         128 :     for ( sal_Int32 nInd = 0; nInd < aProps.getLength(); nInd++ )
     737             :     {
     738          96 :         if ( aProps[nInd].Name.equals( aComprPropName ) )
     739             :         {
     740          32 :             bCompressedIsSet = true;
     741          32 :             aProps[nInd].Value >>= bCompressed;
     742             :         }
     743         192 :         else if ( ( m_nStorageType == embed::StorageFormats::OFOPXML || m_nStorageType == embed::StorageFormats::PACKAGE )
     744         128 :                && aProps[nInd].Name.equals( aMedTypePropName ) )
     745             :         {
     746          32 :             xPropertySet->setPropertyValue( aProps[nInd].Name, aProps[nInd].Value );
     747             :         }
     748          32 :         else if ( m_nStorageType == embed::StorageFormats::PACKAGE && aProps[nInd].Name == "UseCommonStoragePasswordEncryption" )
     749          32 :             aProps[nInd].Value >>= m_bUseCommonEncryption;
     750             :         else
     751           0 :             throw lang::IllegalArgumentException();
     752             : 
     753             :         // if there are cached properties update them
     754          96 :         if ( aProps[nInd].Name.equals( aMedTypePropName ) || aProps[nInd].Name.equals( aComprPropName ) )
     755          64 :             for ( sal_Int32 nMemInd = 0; nMemInd < m_aProps.getLength(); nMemInd++ )
     756             :             {
     757           0 :                 if ( aProps[nInd].Name.equals( m_aProps[nMemInd].Name ) )
     758           0 :                     m_aProps[nMemInd].Value = aProps[nInd].Value;
     759             :             }
     760             :     }
     761             : 
     762          32 :     if ( bCompressedIsSet )
     763             :     {
     764          32 :         xPropertySet->setPropertyValue( aComprPropName, uno::makeAny( bCompressed ) );
     765          32 :         m_bCompressedSetExplicit = true;
     766             :     }
     767             : 
     768          32 :     if ( m_bUseCommonEncryption )
     769             :     {
     770          32 :         if ( m_nStorageType != embed::StorageFormats::PACKAGE )
     771           0 :             throw uno::RuntimeException();
     772             : 
     773             :         // set to be encrypted but do not use encryption key
     774          32 :         xPropertySet->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY,
     775          32 :                                         uno::makeAny( uno::Sequence< beans::NamedValue >() ) );
     776          32 :         xPropertySet->setPropertyValue( "Encrypted", uno::makeAny( true ) );
     777             :     }
     778             : 
     779             :     // the stream should be free soon, after package is stored
     780          32 :     m_bHasDataToFlush = false;
     781          32 :     m_bFlushed = true; // will allow to use transaction on stream level if will need it
     782          64 :     m_bHasInsertedStreamOptimization = true;
     783          32 : }
     784             : 
     785       46056 : void OWriteStream_Impl::Commit()
     786             : {
     787       46056 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
     788             : 
     789             :     SAL_WARN_IF( !m_xPackageStream.is(), "package.xstor", "No package stream is set!" );
     790             : 
     791       46056 :     if ( !m_bHasDataToFlush )
     792       65560 :         return;
     793             : 
     794       53104 :     uno::Reference< packages::XDataSinkEncrSupport > xNewPackageStream;
     795       53104 :     uno::Sequence< uno::Any > aSeq( 1 );
     796       26552 :     aSeq[0] <<= sal_False;
     797             : 
     798       26552 :     if ( m_xCacheStream.is() )
     799             :     {
     800       24078 :         if ( m_pAntiImpl )
     801        4442 :             m_pAntiImpl->DeInit();
     802             : 
     803       24078 :         uno::Reference< io::XInputStream > xInStream( m_xCacheStream->getInputStream(), uno::UNO_SET_THROW );
     804             : 
     805       48156 :         xNewPackageStream = uno::Reference< packages::XDataSinkEncrSupport >(
     806       24078 :                                                         m_xPackage->createInstanceWithArguments( aSeq ),
     807       24078 :                                                         uno::UNO_QUERY_THROW );
     808             : 
     809       24078 :         xNewPackageStream->setDataStream( xInStream );
     810             : 
     811       24078 :         m_xCacheStream = uno::Reference< io::XStream >();
     812       24078 :         m_xCacheSeek = uno::Reference< io::XSeekable >();
     813             : 
     814             :     }
     815        2474 :     else if ( !m_aTempURL.isEmpty() )
     816             :     {
     817         518 :         if ( m_pAntiImpl )
     818         126 :             m_pAntiImpl->DeInit();
     819             : 
     820         518 :         uno::Reference< io::XInputStream > xInStream;
     821             :         try
     822             :         {
     823         518 :             xInStream.set( static_cast< io::XInputStream* >( new OSelfTerminateFileStream( m_xContext, m_aTempURL ) ), uno::UNO_QUERY );
     824             :         }
     825           0 :         catch( const uno::Exception& )
     826             :         {
     827             :         }
     828             : 
     829         518 :         if ( !xInStream.is() )
     830           0 :             throw io::IOException();
     831             : 
     832        1036 :         xNewPackageStream = uno::Reference< packages::XDataSinkEncrSupport >(
     833         518 :                                                         m_xPackage->createInstanceWithArguments( aSeq ),
     834         518 :                                                         uno::UNO_QUERY_THROW );
     835             : 
     836             :         // TODO/NEW: Let the temporary file be removed after commit
     837         518 :         xNewPackageStream->setDataStream( xInStream );
     838         518 :         m_aTempURL = OUString();
     839             :     }
     840             :     else // if ( m_bHasInsertedStreamOptimization )
     841             :     {
     842             :         // if the optimization is used the stream can be accessed directly
     843        1956 :         xNewPackageStream = m_xPackageStream;
     844             :     }
     845             : 
     846             :     // copy properties to the package stream
     847       53104 :     uno::Reference< beans::XPropertySet > xPropertySet( xNewPackageStream, uno::UNO_QUERY );
     848       26552 :     if ( !xPropertySet.is() )
     849           0 :         throw uno::RuntimeException();
     850             : 
     851      116500 :     for ( sal_Int32 nInd = 0; nInd < m_aProps.getLength(); nInd++ )
     852             :     {
     853       89948 :         if ( m_aProps[nInd].Name == "Size" )
     854             :         {
     855       26552 :             if ( m_pAntiImpl && !m_bHasInsertedStreamOptimization && m_pAntiImpl->m_xSeekable.is() )
     856             :             {
     857           0 :                 m_aProps[nInd].Value <<= m_pAntiImpl->m_xSeekable->getLength();
     858           0 :                 xPropertySet->setPropertyValue( m_aProps[nInd].Name, m_aProps[nInd].Value );
     859             :             }
     860             :         }
     861             :         else
     862       63396 :             xPropertySet->setPropertyValue( m_aProps[nInd].Name, m_aProps[nInd].Value );
     863             :     }
     864             : 
     865       26552 :     if ( m_bUseCommonEncryption )
     866             :     {
     867       10286 :         if ( m_nStorageType != embed::StorageFormats::PACKAGE )
     868           0 :             throw uno::RuntimeException();
     869             : 
     870             :         // set to be encrypted but do not use encryption key
     871       10286 :         xPropertySet->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY,
     872       10286 :                                         uno::makeAny( uno::Sequence< beans::NamedValue >() ) );
     873       10286 :         xPropertySet->setPropertyValue( "Encrypted",
     874       10286 :                                         uno::makeAny( true ) );
     875             :     }
     876       16266 :     else if ( m_bHasCachedEncryptionData )
     877             :     {
     878           0 :         if ( m_nStorageType != embed::StorageFormats::PACKAGE )
     879           0 :             throw uno::RuntimeException();
     880             : 
     881           0 :         xPropertySet->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY,
     882           0 :                                         uno::makeAny( m_aEncryptionData.getAsConstNamedValueList() ) );
     883             :     }
     884             : 
     885             :     // the stream should be free soon, after package is stored
     886       26552 :     m_xPackageStream = xNewPackageStream;
     887       26552 :     m_bHasDataToFlush = false;
     888       53104 :     m_bFlushed = true; // will allow to use transaction on stream level if will need it
     889             : }
     890             : 
     891           0 : void OWriteStream_Impl::Revert()
     892             : {
     893             :     // can be called only from parent storage
     894             :     // means complete reload of the stream
     895             : 
     896           0 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
     897             : 
     898           0 :     if ( !m_bHasDataToFlush )
     899           0 :         return; // nothing to do
     900             : 
     901             :     OSL_ENSURE( !m_aTempURL.isEmpty() || m_xCacheStream.is(), "The temporary must exist!\n" );
     902             : 
     903           0 :     if ( m_xCacheStream.is() )
     904             :     {
     905           0 :         m_xCacheStream = uno::Reference< io::XStream >();
     906           0 :         m_xCacheSeek = uno::Reference< io::XSeekable >();
     907             :     }
     908             : 
     909           0 :     if ( !m_aTempURL.isEmpty() )
     910             :     {
     911           0 :         KillFile( m_aTempURL, comphelper::getProcessComponentContext() );
     912           0 :         m_aTempURL = OUString();
     913             :     }
     914             : 
     915           0 :     m_aProps.realloc( 0 );
     916             : 
     917           0 :     m_bHasDataToFlush = false;
     918             : 
     919           0 :     m_bUseCommonEncryption = true;
     920           0 :     m_bHasCachedEncryptionData = false;
     921           0 :     m_aEncryptionData.clear();
     922             : 
     923           0 :     if ( m_nStorageType == embed::StorageFormats::OFOPXML )
     924             :     {
     925             :         // currently the relations storage is changed only on commit
     926           0 :         m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
     927           0 :         m_aNewRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
     928           0 :         if ( m_xOrigRelInfoStream.is() )
     929             :         {
     930             :             // the original stream is still here, that means that it was not parsed
     931           0 :             m_aOrigRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
     932           0 :             m_nRelInfoStatus = RELINFO_NO_INIT;
     933             :         }
     934             :         else
     935             :         {
     936             :             // the original stream was already parsed
     937           0 :             if ( !m_bOrigRelInfoBroken )
     938           0 :                 m_nRelInfoStatus = RELINFO_READ;
     939             :             else
     940           0 :                 m_nRelInfoStatus = RELINFO_BROKEN;
     941             :         }
     942           0 :     }
     943             : }
     944             : 
     945      152560 : uno::Sequence< beans::PropertyValue > OWriteStream_Impl::GetStreamProperties()
     946             : {
     947      152560 :     if ( !m_aProps.getLength() )
     948       89450 :         m_aProps = ReadPackageStreamProperties();
     949             : 
     950      152560 :     return m_aProps;
     951             : }
     952             : 
     953       77126 : uno::Sequence< beans::PropertyValue > OWriteStream_Impl::InsertOwnProps(
     954             :                                                                     const uno::Sequence< beans::PropertyValue >& aProps,
     955             :                                                                     bool bUseCommonEncryption )
     956             : {
     957       77126 :     uno::Sequence< beans::PropertyValue > aResult( aProps );
     958       77126 :     sal_Int32 nLen = aResult.getLength();
     959             : 
     960       77126 :     if ( m_nStorageType == embed::StorageFormats::PACKAGE )
     961             :     {
     962       22730 :         for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
     963       18184 :             if ( aResult[nInd].Name == "UseCommonStoragePasswordEncryption" )
     964             :             {
     965           0 :                 aResult[nInd].Value <<= bUseCommonEncryption;
     966           0 :                 return aResult;
     967             :             }
     968             : 
     969        4546 :         aResult.realloc( ++nLen );
     970        4546 :         aResult[nLen - 1].Name = "UseCommonStoragePasswordEncryption";
     971        4546 :         aResult[nLen - 1].Value <<= bUseCommonEncryption;
     972             :     }
     973       72580 :     else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
     974             :     {
     975       57498 :         ReadRelInfoIfNecessary();
     976             : 
     977       57498 :         uno::Any aValue;
     978       57498 :         if ( m_nRelInfoStatus == RELINFO_READ )
     979       57498 :             aValue <<= m_aOrigRelInfo;
     980           0 :         else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ || m_nRelInfoStatus == RELINFO_CHANGED )
     981           0 :             aValue <<= m_aNewRelInfo;
     982             :         else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
     983           0 :             throw io::IOException( "Wrong relinfo stream!" );
     984             : 
     985      229992 :         for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
     986      172494 :             if ( aResult[nInd].Name == "RelationsInfo" )
     987             :             {
     988           0 :                 aResult[nInd].Value = aValue;
     989           0 :                 return aResult;
     990             :             }
     991             : 
     992       57498 :         aResult.realloc( ++nLen );
     993       57498 :         aResult[nLen - 1].Name = "RelationsInfo";
     994       57498 :         aResult[nLen - 1].Value = aValue;
     995             :     }
     996             : 
     997       77126 :     return aResult;
     998             : }
     999             : 
    1000       21002 : bool OWriteStream_Impl::IsTransacted()
    1001             : {
    1002       21002 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
    1003       21002 :     return ( m_pAntiImpl && m_pAntiImpl->m_bTransacted );
    1004             : }
    1005             : 
    1006      168392 : void OWriteStream_Impl::ReadRelInfoIfNecessary()
    1007             : {
    1008      168392 :     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
    1009      197264 :         return;
    1010             : 
    1011      139520 :     if ( m_nRelInfoStatus == RELINFO_NO_INIT )
    1012             :     {
    1013             :         try
    1014             :         {
    1015             :             // Init from original stream
    1016       63414 :             if ( m_xOrigRelInfoStream.is() )
    1017       14324 :                 m_aOrigRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
    1018             :                                         m_xOrigRelInfoStream,
    1019             :                                         "_rels/*.rels",
    1020        7162 :                                         m_xContext );
    1021             : 
    1022             :             // in case of success the stream must be thrown away, that means that the OrigRelInfo is initialized
    1023             :             // the reason for this is that the original stream might not be seekable ( at the same time the new
    1024             :             // provided stream must be seekable ), so it must be read only once
    1025       63414 :             m_xOrigRelInfoStream = uno::Reference< io::XInputStream >();
    1026       63414 :             m_nRelInfoStatus = RELINFO_READ;
    1027             :         }
    1028           0 :         catch( const uno::Exception& rException )
    1029             :         {
    1030           0 :             AddLog( rException.Message );
    1031           0 :             AddLog( "Quiet exception" );
    1032             : 
    1033           0 :             m_nRelInfoStatus = RELINFO_BROKEN;
    1034           0 :             m_bOrigRelInfoBroken = true;
    1035             :         }
    1036             :     }
    1037       76106 :     else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
    1038             :     {
    1039             :         // Init from the new stream
    1040             :         try
    1041             :         {
    1042           0 :             if ( m_xNewRelInfoStream.is() )
    1043           0 :                 m_aNewRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
    1044             :                                         m_xNewRelInfoStream,
    1045             :                                         "_rels/*.rels",
    1046           0 :                                         m_xContext );
    1047             : 
    1048           0 :             m_nRelInfoStatus = RELINFO_CHANGED_STREAM_READ;
    1049             :         }
    1050           0 :         catch( const uno::Exception& )
    1051             :         {
    1052           0 :             m_nRelInfoStatus = RELINFO_CHANGED_BROKEN;
    1053             :         }
    1054             :     }
    1055             : }
    1056             : 
    1057       89450 : uno::Sequence< beans::PropertyValue > OWriteStream_Impl::ReadPackageStreamProperties()
    1058             : {
    1059       89450 :     sal_Int32 nPropNum = 0;
    1060       89450 :     if ( m_nStorageType == embed::StorageFormats::ZIP )
    1061       14744 :         nPropNum = 2;
    1062       74706 :     else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
    1063       63414 :         nPropNum = 3;
    1064       11292 :     else if ( m_nStorageType == embed::StorageFormats::PACKAGE )
    1065       11292 :         nPropNum = 4;
    1066       89450 :     uno::Sequence< beans::PropertyValue > aResult( nPropNum );
    1067             : 
    1068             :     // The "Compressed" property must be set after "MediaType" property,
    1069             :     // since the setting of the last one can change the value of the first one
    1070             : 
    1071       89450 :     if ( m_nStorageType == embed::StorageFormats::OFOPXML || m_nStorageType == embed::StorageFormats::PACKAGE )
    1072             :     {
    1073       74706 :         aResult[0].Name = "MediaType";
    1074       74706 :         aResult[1].Name = "Compressed";
    1075       74706 :         aResult[2].Name = "Size";
    1076             : 
    1077      149412 :         if ( m_nStorageType == embed::StorageFormats::PACKAGE )
    1078       11292 :             aResult[3].Name = "Encrypted";
    1079             :     }
    1080             :     else
    1081             :     {
    1082       14744 :         aResult[0].Name = "Compressed";
    1083       14744 :         aResult[1].Name = "Size";
    1084             :     }
    1085             : 
    1086             :     // TODO: may be also raw stream should be marked
    1087             : 
    1088      178900 :     uno::Reference< beans::XPropertySet > xPropSet( m_xPackageStream, uno::UNO_QUERY );
    1089       89450 :     if ( xPropSet.is() )
    1090             :     {
    1091      354348 :         for ( sal_Int32 nInd = 0; nInd < aResult.getLength(); nInd++ )
    1092             :         {
    1093             :             try {
    1094      264898 :                 aResult[nInd].Value = xPropSet->getPropertyValue( aResult[nInd].Name );
    1095             :             }
    1096           0 :             catch( const uno::Exception& rException )
    1097             :             {
    1098           0 :                 AddLog( rException.Message );
    1099           0 :                 AddLog( "Quiet exception" );
    1100             : 
    1101             :                 SAL_WARN( "package.xstor", "A property can't be retrieved!" );
    1102             :             }
    1103             :         }
    1104             :     }
    1105             :     else
    1106             :     {
    1107             :         SAL_WARN( "package.xstor", "Can not get properties from a package stream!" );
    1108           0 :         throw uno::RuntimeException();
    1109             :     }
    1110             : 
    1111      178900 :     return aResult;
    1112             : }
    1113             : 
    1114           0 : void OWriteStream_Impl::CopyInternallyTo_Impl( const uno::Reference< io::XStream >& xDestStream,
    1115             :                                                 const ::comphelper::SequenceAsHashMap& aEncryptionData )
    1116             : {
    1117           0 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
    1118             : 
    1119             :     SAL_WARN_IF( m_bUseCommonEncryption, "package.xstor", "The stream can not be encrypted!" );
    1120             : 
    1121           0 :     if ( m_nStorageType != embed::StorageFormats::PACKAGE )
    1122           0 :         throw packages::NoEncryptionException();
    1123             : 
    1124           0 :     if ( m_pAntiImpl )
    1125             :     {
    1126           0 :         m_pAntiImpl->CopyToStreamInternally_Impl( xDestStream );
    1127             :     }
    1128             :     else
    1129             :     {
    1130           0 :         uno::Reference< io::XStream > xOwnStream = GetStream( embed::ElementModes::READ, aEncryptionData, false );
    1131           0 :         if ( !xOwnStream.is() )
    1132           0 :             throw io::IOException(); // TODO
    1133             : 
    1134           0 :         OStorage_Impl::completeStorageStreamCopy_Impl( xOwnStream, xDestStream, m_nStorageType, GetAllRelationshipsIfAny() );
    1135             :     }
    1136             : 
    1137           0 :     uno::Reference< embed::XEncryptionProtectedSource2 > xEncr( xDestStream, uno::UNO_QUERY );
    1138           0 :     if ( xEncr.is() )
    1139           0 :         xEncr->setEncryptionData( aEncryptionData.getAsConstNamedValueList() );
    1140           0 : }
    1141             : 
    1142        8546 : uno::Sequence< uno::Sequence< beans::StringPair > > OWriteStream_Impl::GetAllRelationshipsIfAny()
    1143             : {
    1144        8546 :     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
    1145         282 :         return uno::Sequence< uno::Sequence< beans::StringPair > >();
    1146             : 
    1147        8264 :     ReadRelInfoIfNecessary();
    1148             : 
    1149        8264 :     if ( m_nRelInfoStatus == RELINFO_READ )
    1150        2664 :         return m_aOrigRelInfo;
    1151        5600 :     else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ || m_nRelInfoStatus == RELINFO_CHANGED )
    1152        5600 :         return m_aNewRelInfo;
    1153             :     else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
    1154           0 :             throw io::IOException( "Wrong relinfo stream!" );
    1155             : }
    1156             : 
    1157         282 : void OWriteStream_Impl::CopyInternallyTo_Impl( const uno::Reference< io::XStream >& xDestStream )
    1158             : {
    1159         282 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
    1160             : 
    1161         282 :     if ( m_pAntiImpl )
    1162             :     {
    1163           0 :         m_pAntiImpl->CopyToStreamInternally_Impl( xDestStream );
    1164             :     }
    1165             :     else
    1166             :     {
    1167         282 :         uno::Reference< io::XStream > xOwnStream = GetStream( embed::ElementModes::READ, false );
    1168         282 :         if ( !xOwnStream.is() )
    1169           0 :             throw io::IOException(); // TODO
    1170             : 
    1171         284 :         OStorage_Impl::completeStorageStreamCopy_Impl( xOwnStream, xDestStream, m_nStorageType, GetAllRelationshipsIfAny() );
    1172         282 :     }
    1173         280 : }
    1174             : 
    1175          38 : uno::Reference< io::XStream > OWriteStream_Impl::GetStream( sal_Int32 nStreamMode, const ::comphelper::SequenceAsHashMap& aEncryptionData, bool bHierarchyAccess )
    1176             : {
    1177          38 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
    1178             : 
    1179             :     SAL_WARN_IF( !m_xPackageStream.is(), "package.xstor", "No package stream is set!" );
    1180             : 
    1181          38 :     if ( m_pAntiImpl )
    1182           0 :         throw io::IOException(); // TODO:
    1183             : 
    1184          38 :     if ( !IsEncrypted() )
    1185           0 :         throw packages::NoEncryptionException();
    1186             : 
    1187          38 :     uno::Reference< io::XStream > xResultStream;
    1188             : 
    1189          76 :     uno::Reference< beans::XPropertySet > xPropertySet( m_xPackageStream, uno::UNO_QUERY );
    1190          38 :     if ( !xPropertySet.is() )
    1191           0 :         throw uno::RuntimeException();
    1192             : 
    1193          38 :     if ( m_bHasCachedEncryptionData )
    1194             :     {
    1195           2 :         if ( !::package::PackageEncryptionDatasEqual( m_aEncryptionData, aEncryptionData ) )
    1196           0 :             throw packages::WrongPasswordException();
    1197             : 
    1198             :         // the correct key must be set already
    1199           2 :         xResultStream = GetStream_Impl( nStreamMode, bHierarchyAccess );
    1200             :     }
    1201             :     else
    1202             :     {
    1203          36 :         SetEncryptionKeyProperty_Impl( xPropertySet, aEncryptionData.getAsConstNamedValueList() );
    1204             : 
    1205             :         try {
    1206          36 :             xResultStream = GetStream_Impl( nStreamMode, bHierarchyAccess );
    1207             : 
    1208          36 :             m_bUseCommonEncryption = false; // very important to set it to false
    1209          36 :             m_bHasCachedEncryptionData = true;
    1210          36 :             m_aEncryptionData = aEncryptionData;
    1211             :         }
    1212           0 :         catch( const packages::WrongPasswordException& rWrongPasswordException )
    1213             :         {
    1214           0 :             SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< beans::NamedValue >() );
    1215           0 :             AddLog( rWrongPasswordException.Message );
    1216           0 :             AddLog( "Rethrow" );
    1217           0 :             throw;
    1218             :         }
    1219           0 :         catch ( const uno::Exception& rException )
    1220             :         {
    1221           0 :             AddLog( rException.Message );
    1222           0 :             AddLog( "Quiet exception" );
    1223             : 
    1224             :             SAL_WARN( "package.xstor", "Can't write encryption related properties!" );
    1225           0 :             SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< beans::NamedValue >() );
    1226           0 :             throw io::IOException(); // TODO:
    1227             :         }
    1228             :     }
    1229             : 
    1230             :     SAL_WARN_IF( !xResultStream.is(), "package.xstor", "In case stream can not be retrieved an exception must be thrown!" );
    1231             : 
    1232          76 :     return xResultStream;
    1233             : }
    1234             : 
    1235      102628 : uno::Reference< io::XStream > OWriteStream_Impl::GetStream( sal_Int32 nStreamMode, bool bHierarchyAccess )
    1236             : {
    1237      102628 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
    1238             : 
    1239             :     SAL_WARN_IF( !m_xPackageStream.is(), "package.xstor", "No package stream is set!" );
    1240             : 
    1241      102628 :     if ( m_pAntiImpl )
    1242           0 :         throw io::IOException(); // TODO:
    1243             : 
    1244      102628 :     uno::Reference< io::XStream > xResultStream;
    1245             : 
    1246      102628 :     if ( IsEncrypted() )
    1247             :     {
    1248          36 :         ::comphelper::SequenceAsHashMap aGlobalEncryptionData;
    1249             :         try
    1250             :         {
    1251          36 :             aGlobalEncryptionData = GetCommonRootEncryptionData();
    1252             :         }
    1253           2 :         catch( const packages::NoEncryptionException& rNoEncryptionException )
    1254             :         {
    1255           2 :             AddLog( rNoEncryptionException.Message );
    1256           2 :             AddLog( "Rethrow" );
    1257             : 
    1258           2 :             throw packages::WrongPasswordException();
    1259             :         }
    1260             : 
    1261          34 :         xResultStream = GetStream( nStreamMode, aGlobalEncryptionData, bHierarchyAccess );
    1262             :     }
    1263             :     else
    1264      102592 :         xResultStream = GetStream_Impl( nStreamMode, bHierarchyAccess );
    1265             : 
    1266      102628 :     return xResultStream;
    1267             : }
    1268             : 
    1269      102630 : uno::Reference< io::XStream > OWriteStream_Impl::GetStream_Impl( sal_Int32 nStreamMode, bool bHierarchyAccess )
    1270             : {
    1271             :     // private method, no mutex is used
    1272      102630 :     GetStreamProperties();
    1273             : 
    1274             :     // TODO/LATER: this info might be read later, on demand in future
    1275      102630 :     ReadRelInfoIfNecessary();
    1276             : 
    1277      102630 :     if ( ( nStreamMode & embed::ElementModes::READWRITE ) == embed::ElementModes::READ )
    1278             :     {
    1279       42422 :         uno::Reference< io::XInputStream > xInStream;
    1280       42422 :         if ( m_xCacheStream.is() || !m_aTempURL.isEmpty() )
    1281           2 :             xInStream = GetTempFileAsInputStream(); //TODO:
    1282             :         else
    1283       42420 :             xInStream = m_xPackageStream->getDataStream();
    1284             : 
    1285             :         // The stream does not exist in the storage
    1286       42422 :         if ( !xInStream.is() )
    1287           0 :             throw io::IOException();
    1288             : 
    1289       42422 :         OInputCompStream* pStream = new OInputCompStream( *this, xInStream, InsertOwnProps( m_aProps, m_bUseCommonEncryption ), m_nStorageType );
    1290             :         uno::Reference< io::XStream > xCompStream(
    1291             :                         static_cast< ::cppu::OWeakObject* >( pStream ),
    1292       84844 :                         uno::UNO_QUERY );
    1293             :         SAL_WARN_IF( !xCompStream.is(), "package.xstor", "OInputCompStream MUST provide XStream interfaces!" );
    1294             : 
    1295       42422 :         m_aInputStreamsList.push_back( pStream );
    1296       84844 :         return xCompStream;
    1297             :     }
    1298       60208 :     else if ( ( nStreamMode & embed::ElementModes::READWRITE ) == embed::ElementModes::SEEKABLEREAD )
    1299             :     {
    1300       34656 :         if ( !m_xCacheStream.is() && m_aTempURL.isEmpty() && !( m_xPackageStream->getDataStream().is() ) )
    1301             :         {
    1302             :             // The stream does not exist in the storage
    1303           0 :             throw io::IOException();
    1304             :         }
    1305             : 
    1306       34656 :         uno::Reference< io::XInputStream > xInStream;
    1307             : 
    1308       34656 :         xInStream = GetTempFileAsInputStream(); //TODO:
    1309             : 
    1310       34656 :         if ( !xInStream.is() )
    1311           0 :             throw io::IOException();
    1312             : 
    1313       34656 :         OInputSeekStream* pStream = new OInputSeekStream( *this, xInStream, InsertOwnProps( m_aProps, m_bUseCommonEncryption ), m_nStorageType );
    1314             :         uno::Reference< io::XStream > xSeekStream(
    1315             :                         static_cast< ::cppu::OWeakObject* >( pStream ),
    1316       69312 :                         uno::UNO_QUERY );
    1317             :         SAL_WARN_IF( !xSeekStream.is(), "package.xstor", "OInputSeekStream MUST provide XStream interfaces!" );
    1318             : 
    1319       34656 :         m_aInputStreamsList.push_back( pStream );
    1320       69312 :         return xSeekStream;
    1321             :     }
    1322       25552 :     else if ( ( nStreamMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE )
    1323             :     {
    1324       25552 :         if ( !m_aInputStreamsList.empty() )
    1325           0 :             throw io::IOException(); // TODO:
    1326             : 
    1327       25552 :         uno::Reference< io::XStream > xStream;
    1328       25552 :         if ( ( nStreamMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
    1329             :         {
    1330       11200 :             if ( !m_aTempURL.isEmpty() )
    1331             :             {
    1332           0 :                 KillFile( m_aTempURL, comphelper::getProcessComponentContext() );
    1333           0 :                 m_aTempURL = OUString();
    1334             :             }
    1335       11200 :             if ( m_xCacheStream.is() )
    1336           0 :                 CleanCacheStream();
    1337             : 
    1338       11200 :             m_bHasDataToFlush = true;
    1339             : 
    1340             :             // this call is triggered by the parent and it will recognize the change of the state
    1341       11200 :             if ( m_pParent )
    1342       11200 :                 m_pParent->m_bIsModified = true;
    1343             : 
    1344       11200 :             xStream = CreateMemoryStream( m_xContext );
    1345       11196 :             m_xCacheSeek.set( xStream, uno::UNO_QUERY_THROW );
    1346       11196 :             m_xCacheStream = xStream;
    1347             :         }
    1348       14352 :         else if ( !m_bHasInsertedStreamOptimization )
    1349             :         {
    1350       14352 :             if ( m_aTempURL.isEmpty() && !m_xCacheStream.is() && !( m_xPackageStream->getDataStream().is() ) )
    1351             :             {
    1352             :                 // The stream does not exist in the storage
    1353       13078 :                 m_bHasDataToFlush = true;
    1354             : 
    1355             :                 // this call is triggered by the parent and it will recognize the change of the state
    1356       13078 :                 if ( m_pParent )
    1357       13078 :                     m_pParent->m_bIsModified = true;
    1358       13078 :                 xStream = GetTempFileAsStream();
    1359             :             }
    1360             : 
    1361             :             // if the stream exists the temporary file is created on demand
    1362             :             // xStream = GetTempFileAsStream();
    1363             :         }
    1364             : 
    1365       25548 :         if ( !xStream.is() )
    1366        1274 :             m_pAntiImpl = new OWriteStream( this, bHierarchyAccess );
    1367             :         else
    1368       24274 :             m_pAntiImpl = new OWriteStream( this, xStream, bHierarchyAccess );
    1369             : 
    1370             :         uno::Reference< io::XStream > xWriteStream =
    1371       25548 :                                 uno::Reference< io::XStream >( static_cast< ::cppu::OWeakObject* >( m_pAntiImpl ),
    1372       51096 :                                                                 uno::UNO_QUERY );
    1373             : 
    1374             :         SAL_WARN_IF( !xWriteStream.is(), "package.xstor", "OWriteStream MUST implement XStream && XComponent interfaces!" );
    1375             : 
    1376       51100 :         return xWriteStream;
    1377             :     }
    1378             : 
    1379           0 :     throw lang::IllegalArgumentException(); // TODO
    1380             : }
    1381             : 
    1382           0 : uno::Reference< io::XInputStream > OWriteStream_Impl::GetPlainRawInStream()
    1383             : {
    1384           0 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
    1385             : 
    1386             :     SAL_WARN_IF( !m_xPackageStream.is(), "package.xstor", "No package stream is set!" );
    1387             : 
    1388             :     // this method is used only internally, this stream object should not go outside of this implementation
    1389             :     // if ( m_pAntiImpl )
    1390             :     //  throw io::IOException(); // TODO:
    1391             : 
    1392           0 :     return m_xPackageStream->getPlainRawStream();
    1393             : }
    1394             : 
    1395           2 : uno::Reference< io::XInputStream > OWriteStream_Impl::GetRawInStream()
    1396             : {
    1397           2 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
    1398             : 
    1399             :     SAL_WARN_IF( !m_xPackageStream.is(), "package.xstor", "No package stream is set!" );
    1400             : 
    1401           2 :     if ( m_pAntiImpl )
    1402           0 :         throw io::IOException(); // TODO:
    1403             : 
    1404             :     SAL_WARN_IF( !IsEncrypted(), "package.xstor", "Impossible to get raw representation for nonencrypted stream!" );
    1405           2 :     if ( !IsEncrypted() )
    1406           0 :         throw packages::NoEncryptionException();
    1407             : 
    1408           2 :     return m_xPackageStream->getRawStream();
    1409             : }
    1410             : 
    1411          36 : ::comphelper::SequenceAsHashMap OWriteStream_Impl::GetCommonRootEncryptionData()
    1412             :     throw ( packages::NoEncryptionException )
    1413             : {
    1414          36 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
    1415             : 
    1416          36 :     if ( m_nStorageType != embed::StorageFormats::PACKAGE || !m_pParent )
    1417           0 :         throw packages::NoEncryptionException();
    1418             : 
    1419          38 :     return m_pParent->GetCommonRootEncryptionData();
    1420             : }
    1421             : 
    1422       76924 : void OWriteStream_Impl::InputStreamDisposed( OInputCompStream* pStream )
    1423             : {
    1424       76924 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
    1425       76924 :     m_aInputStreamsList.remove( pStream );
    1426       76924 : }
    1427             : 
    1428          48 : void OWriteStream_Impl::CreateReadonlyCopyBasedOnData( const uno::Reference< io::XInputStream >& xDataToCopy, const uno::Sequence< beans::PropertyValue >& aProps, bool, uno::Reference< io::XStream >& xTargetStream )
    1429             : {
    1430          48 :     uno::Reference < io::XStream > xTempFile;
    1431          48 :     if ( !xTargetStream.is() )
    1432          96 :         xTempFile = uno::Reference < io::XStream >(
    1433             :             io::TempFile::create(m_xContext),
    1434          48 :             uno::UNO_QUERY );
    1435             :     else
    1436           0 :         xTempFile = xTargetStream;
    1437             : 
    1438          96 :     uno::Reference < io::XSeekable > xTempSeek( xTempFile, uno::UNO_QUERY );
    1439          48 :     if ( !xTempSeek.is() )
    1440           0 :         throw uno::RuntimeException(); // TODO
    1441             : 
    1442          96 :     uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
    1443          48 :     if ( !xTempOut.is() )
    1444           0 :         throw uno::RuntimeException();
    1445             : 
    1446          48 :     if ( xDataToCopy.is() )
    1447          48 :         ::comphelper::OStorageHelper::CopyInputToOutput( xDataToCopy, xTempOut );
    1448             : 
    1449          48 :     xTempOut->closeOutput();
    1450          48 :     xTempSeek->seek( 0 );
    1451             : 
    1452          96 :     uno::Reference< io::XInputStream > xInStream = xTempFile->getInputStream();
    1453          48 :     if ( !xInStream.is() )
    1454           0 :         throw io::IOException();
    1455             : 
    1456             :     // TODO: remember last state of m_bUseCommonEncryption
    1457          48 :     if ( !xTargetStream.is() )
    1458         144 :         xTargetStream = uno::Reference< io::XStream > (
    1459             :             static_cast< ::cppu::OWeakObject* >(
    1460          48 :                 new OInputSeekStream( xInStream, InsertOwnProps( aProps, m_bUseCommonEncryption ), m_nStorageType ) ),
    1461          96 :             uno::UNO_QUERY_THROW );
    1462          48 : }
    1463             : 
    1464          48 : void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference< io::XStream >& xTargetStream )
    1465             : {
    1466          48 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
    1467             : 
    1468             :     SAL_WARN_IF( !m_xPackageStream.is(), "package.xstor", "The source stream for copying is incomplete!" );
    1469          48 :     if ( !m_xPackageStream.is() )
    1470           0 :         throw uno::RuntimeException();
    1471             : 
    1472          96 :     uno::Reference< io::XInputStream > xDataToCopy;
    1473          48 :     if ( IsEncrypted() )
    1474             :     {
    1475             :         // an encrypted stream must contain input stream
    1476           0 :         ::comphelper::SequenceAsHashMap aGlobalEncryptionData;
    1477             :         try
    1478             :         {
    1479           0 :             aGlobalEncryptionData = GetCommonRootEncryptionData();
    1480             :         }
    1481           0 :         catch( const packages::NoEncryptionException& rNoEncryptionException )
    1482             :         {
    1483           0 :             AddLog( rNoEncryptionException.Message );
    1484           0 :             AddLog( "No Element" );
    1485             : 
    1486           0 :             throw packages::WrongPasswordException();
    1487             :         }
    1488             : 
    1489           0 :         GetCopyOfLastCommit( xTargetStream, aGlobalEncryptionData );
    1490             :     }
    1491             :     else
    1492             :     {
    1493          48 :         xDataToCopy = m_xPackageStream->getDataStream();
    1494             : 
    1495             :         // in case of new inserted package stream it is possible that input stream still was not set
    1496          48 :         GetStreamProperties();
    1497             : 
    1498          48 :         CreateReadonlyCopyBasedOnData( xDataToCopy, m_aProps, m_bUseCommonEncryption, xTargetStream );
    1499          48 :     }
    1500          48 : }
    1501             : 
    1502           0 : void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference< io::XStream >& xTargetStream, const ::comphelper::SequenceAsHashMap& aEncryptionData )
    1503             : {
    1504           0 :     ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
    1505             : 
    1506             :     SAL_WARN_IF( !m_xPackageStream.is(), "package.xstor", "The source stream for copying is incomplete!" );
    1507           0 :     if ( !m_xPackageStream.is() )
    1508           0 :         throw uno::RuntimeException();
    1509             : 
    1510           0 :     if ( !IsEncrypted() )
    1511           0 :         throw packages::NoEncryptionException();
    1512             : 
    1513           0 :     uno::Reference< io::XInputStream > xDataToCopy;
    1514             : 
    1515           0 :     if ( m_bHasCachedEncryptionData )
    1516             :     {
    1517             :         // TODO: introduce last commited cashed password information and use it here
    1518             :         // that means "use common pass" also should be remembered on flash
    1519           0 :         uno::Sequence< beans::NamedValue > aKey = aEncryptionData.getAsConstNamedValueList();
    1520             : 
    1521           0 :         uno::Reference< beans::XPropertySet > xProps( m_xPackageStream, uno::UNO_QUERY );
    1522           0 :         if ( !xProps.is() )
    1523           0 :             throw uno::RuntimeException();
    1524             : 
    1525           0 :         bool bEncr = false;
    1526           0 :         xProps->getPropertyValue( "Encrypted" ) >>= bEncr;
    1527           0 :         if ( !bEncr )
    1528           0 :             throw packages::NoEncryptionException();
    1529             : 
    1530           0 :         uno::Sequence< beans::NamedValue > aPackKey;
    1531           0 :         xProps->getPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY ) >>= aPackKey;
    1532           0 :         if ( !SequencesEqual( aKey, aPackKey ) )
    1533           0 :             throw packages::WrongPasswordException();
    1534             : 
    1535             :         // the correct key must be set already
    1536           0 :         xDataToCopy = m_xPackageStream->getDataStream();
    1537             :     }
    1538             :     else
    1539             :     {
    1540           0 :         uno::Reference< beans::XPropertySet > xPropertySet( m_xPackageStream, uno::UNO_QUERY );
    1541           0 :         SetEncryptionKeyProperty_Impl( xPropertySet, aEncryptionData.getAsConstNamedValueList() );
    1542             : 
    1543             :         try {
    1544           0 :             xDataToCopy = m_xPackageStream->getDataStream();
    1545             : 
    1546           0 :             if ( !xDataToCopy.is() )
    1547             :             {
    1548             :                 SAL_WARN( "package.xstor", "Encrypted ZipStream must already have input stream inside!" );
    1549           0 :                 SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< beans::NamedValue >() );
    1550             :             }
    1551             :         }
    1552           0 :         catch( const uno::Exception& rException )
    1553             :         {
    1554             :             SAL_WARN( "package.xstor", "Can't open encrypted stream!" );
    1555           0 :             SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< beans::NamedValue >() );
    1556           0 :             AddLog( rException.Message );
    1557           0 :             AddLog( "Rethrow" );
    1558           0 :             throw;
    1559             :         }
    1560             : 
    1561           0 :         SetEncryptionKeyProperty_Impl( xPropertySet, uno::Sequence< beans::NamedValue >() );
    1562             :     }
    1563             : 
    1564             :     // in case of new inserted package stream it is possible that input stream still was not set
    1565           0 :     GetStreamProperties();
    1566             : 
    1567           0 :     CreateReadonlyCopyBasedOnData( xDataToCopy, m_aProps, m_bUseCommonEncryption, xTargetStream );
    1568           0 : }
    1569             : 
    1570       15026 : void OWriteStream_Impl::CommitStreamRelInfo( const uno::Reference< embed::XStorage >& xRelStorage, const OUString& aOrigStreamName, const OUString& aNewStreamName )
    1571             : {
    1572             :     // at this point of time the old stream must be already cleaned
    1573             :     OSL_ENSURE( m_nStorageType == embed::StorageFormats::OFOPXML, "The method should be used only with OFOPXML format!\n" );
    1574             : 
    1575       15026 :     if ( m_nStorageType == embed::StorageFormats::OFOPXML )
    1576             :     {
    1577             :         OSL_ENSURE( !aOrigStreamName.isEmpty() && !aNewStreamName.isEmpty() && xRelStorage.is(),
    1578             :                     "Wrong relation persistence information is provided!\n" );
    1579             : 
    1580       15026 :         if ( !xRelStorage.is() || aOrigStreamName.isEmpty() || aNewStreamName.isEmpty() )
    1581           0 :             throw uno::RuntimeException();
    1582             : 
    1583       15026 :         if ( m_nRelInfoStatus == RELINFO_BROKEN || m_nRelInfoStatus == RELINFO_CHANGED_BROKEN )
    1584           0 :             throw io::IOException(); // TODO:
    1585             : 
    1586       15026 :         OUString aOrigRelStreamName = aOrigStreamName;
    1587       15026 :         aOrigRelStreamName += ".rels";
    1588             : 
    1589       30052 :         OUString aNewRelStreamName = aNewStreamName;
    1590       15026 :         aNewRelStreamName += ".rels";
    1591             : 
    1592       15026 :         bool bRenamed = !aOrigRelStreamName.equals( aNewRelStreamName );
    1593       15026 :         if ( m_nRelInfoStatus == RELINFO_CHANGED
    1594       12362 :           || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
    1595       12362 :           || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
    1596             :         {
    1597        2664 :             if ( bRenamed && xRelStorage->hasByName( aOrigRelStreamName ) )
    1598           0 :                 xRelStorage->removeElement( aOrigRelStreamName );
    1599             : 
    1600        2664 :             if ( m_nRelInfoStatus == RELINFO_CHANGED )
    1601             :             {
    1602        2664 :                 if ( m_aNewRelInfo.getLength() )
    1603             :                 {
    1604             :                     uno::Reference< io::XStream > xRelsStream =
    1605        2664 :                         xRelStorage->openStreamElement( aNewRelStreamName,
    1606        2664 :                                                           embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
    1607             : 
    1608        5328 :                     uno::Reference< io::XOutputStream > xOutStream = xRelsStream->getOutputStream();
    1609        2664 :                     if ( !xOutStream.is() )
    1610           0 :                         throw uno::RuntimeException();
    1611             : 
    1612        2664 :                     ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence( xOutStream, m_aNewRelInfo, m_xContext );
    1613             : 
    1614             :                     // set the mediatype
    1615        5328 :                     uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
    1616        2664 :                     xPropSet->setPropertyValue(
    1617             :                         "MediaType",
    1618        2664 :                         uno::makeAny( OUString("application/vnd.openxmlformats-package.relationships+xml" ) ) );
    1619             : 
    1620        5328 :                     m_nRelInfoStatus = RELINFO_READ;
    1621             :                 }
    1622             :             }
    1623           0 :             else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
    1624           0 :                       || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
    1625             :             {
    1626             :                 uno::Reference< io::XStream > xRelsStream =
    1627           0 :                     xRelStorage->openStreamElement( aNewRelStreamName,
    1628           0 :                                                         embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
    1629             : 
    1630           0 :                 uno::Reference< io::XOutputStream > xOutputStream = xRelsStream->getOutputStream();
    1631           0 :                 if ( !xOutputStream.is() )
    1632           0 :                     throw uno::RuntimeException();
    1633             : 
    1634           0 :                 uno::Reference< io::XSeekable > xSeek( m_xNewRelInfoStream, uno::UNO_QUERY_THROW );
    1635           0 :                 xSeek->seek( 0 );
    1636           0 :                 ::comphelper::OStorageHelper::CopyInputToOutput( m_xNewRelInfoStream, xOutputStream );
    1637           0 :                 xSeek->seek( 0 );
    1638             : 
    1639             :                 // set the mediatype
    1640           0 :                 uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
    1641           0 :                 xPropSet->setPropertyValue("MediaType",
    1642           0 :                     uno::makeAny( OUString("application/vnd.openxmlformats-package.relationships+xml" ) ) );
    1643             : 
    1644           0 :                   if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
    1645           0 :                     m_nRelInfoStatus = RELINFO_NO_INIT;
    1646             :                 else
    1647             :                 {
    1648             :                     // the information is already parsed and the stream is stored, no need in temporary stream any more
    1649           0 :                     m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
    1650           0 :                     m_nRelInfoStatus = RELINFO_READ;
    1651           0 :                 }
    1652             :             }
    1653             : 
    1654             :             // the original stream makes no sence after this step
    1655        2664 :             m_xOrigRelInfoStream = m_xNewRelInfoStream;
    1656        2664 :             m_aOrigRelInfo = m_aNewRelInfo;
    1657        2664 :             m_bOrigRelInfoBroken = false;
    1658        2664 :             m_aNewRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
    1659        2664 :             m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
    1660             :         }
    1661             :         else
    1662             :         {
    1663             :             // the stream is not changed but it might be renamed
    1664       12362 :             if ( bRenamed && xRelStorage->hasByName( aOrigRelStreamName ) )
    1665           0 :                 xRelStorage->renameElement( aOrigRelStreamName, aNewRelStreamName );
    1666       15026 :         }
    1667             :     }
    1668       15026 : }
    1669             : 
    1670             : // OWriteStream implementation
    1671             : 
    1672        1274 : OWriteStream::OWriteStream( OWriteStream_Impl* pImpl, bool bTransacted )
    1673             : : m_pImpl( pImpl )
    1674             : , m_bInStreamDisconnected( false )
    1675             : , m_bInitOnDemand( true )
    1676             : , m_nInitPosition( 0 )
    1677        1274 : , m_bTransacted( bTransacted )
    1678             : {
    1679             :     OSL_ENSURE( pImpl, "No base implementation!\n" );
    1680             :     OSL_ENSURE( m_pImpl->m_rMutexRef.Is(), "No mutex!\n" );
    1681             : 
    1682        1274 :     if ( !m_pImpl || !m_pImpl->m_rMutexRef.Is() )
    1683           0 :         throw uno::RuntimeException(); // just a disaster
    1684             : 
    1685        1274 :     m_pData = new WSInternalData_Impl( pImpl->m_rMutexRef, m_pImpl->m_nStorageType );
    1686        1274 : }
    1687             : 
    1688       24274 : OWriteStream::OWriteStream( OWriteStream_Impl* pImpl, uno::Reference< io::XStream > xStream, bool bTransacted )
    1689             : : m_pImpl( pImpl )
    1690             : , m_bInStreamDisconnected( false )
    1691             : , m_bInitOnDemand( false )
    1692             : , m_nInitPosition( 0 )
    1693       24274 : , m_bTransacted( bTransacted )
    1694             : {
    1695             :     OSL_ENSURE( pImpl && xStream.is(), "No base implementation!\n" );
    1696             :     OSL_ENSURE( m_pImpl->m_rMutexRef.Is(), "No mutex!\n" );
    1697             : 
    1698       24274 :     if ( !m_pImpl || !m_pImpl->m_rMutexRef.Is() )
    1699           0 :         throw uno::RuntimeException(); // just a disaster
    1700             : 
    1701       24274 :     m_pData = new WSInternalData_Impl( pImpl->m_rMutexRef, m_pImpl->m_nStorageType );
    1702             : 
    1703       24274 :     if ( xStream.is() )
    1704             :     {
    1705       24274 :         m_xInStream = xStream->getInputStream();
    1706       24274 :         m_xOutStream = xStream->getOutputStream();
    1707       24274 :         m_xSeekable = uno::Reference< io::XSeekable >( xStream, uno::UNO_QUERY );
    1708             :         OSL_ENSURE( m_xInStream.is() && m_xOutStream.is() && m_xSeekable.is(), "Stream implementation is incomplete!\n" );
    1709             :     }
    1710       24274 : }
    1711             : 
    1712       76644 : OWriteStream::~OWriteStream()
    1713             : {
    1714             :     {
    1715       25548 :         ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    1716       25548 :         if ( m_pImpl )
    1717             :         {
    1718       25520 :             m_refCount++;
    1719             :             try {
    1720       25520 :                 dispose();
    1721             :             }
    1722           0 :             catch( const uno::RuntimeException& rRuntimeException )
    1723             :             {
    1724           0 :                 m_pImpl->AddLog( rRuntimeException.Message );
    1725           0 :                 m_pImpl->AddLog( "Quiet exception" );
    1726             :             }
    1727       25548 :         }
    1728             :     }
    1729             : 
    1730       25548 :     if ( m_pData && m_pData->m_pTypeCollection )
    1731           0 :         delete m_pData->m_pTypeCollection;
    1732             : 
    1733       25548 :     if ( m_pData )
    1734       25548 :         delete m_pData;
    1735       51096 : }
    1736             : 
    1737        5020 : void OWriteStream::DeInit()
    1738             : {
    1739        5020 :     if ( !m_pImpl )
    1740        5020 :         return; // do nothing
    1741             : 
    1742        5020 :     if ( m_xSeekable.is() )
    1743        5020 :         m_nInitPosition = m_xSeekable->getPosition();
    1744             : 
    1745        5020 :     m_xInStream = uno::Reference< io::XInputStream >();
    1746        5020 :     m_xOutStream = uno::Reference< io::XOutputStream >();
    1747        5020 :     m_xSeekable = uno::Reference< io::XSeekable >();
    1748        5020 :     m_bInitOnDemand = true;
    1749             : }
    1750             : 
    1751       33342 : void OWriteStream::CheckInitOnDemand()
    1752             : {
    1753       33342 :     if ( !m_pImpl )
    1754             :     {
    1755             :         SAL_INFO("package.xstor", "Disposed!");
    1756           0 :         throw lang::DisposedException();
    1757             :     }
    1758             : 
    1759       33342 :     if ( m_bInitOnDemand )
    1760             :     {
    1761             :         SAL_INFO( "package.xstor", "package (mv76033) OWriteStream::CheckInitOnDemand, initializing" );
    1762        1388 :         uno::Reference< io::XStream > xStream = m_pImpl->GetTempFileAsStream();
    1763        1386 :         if ( xStream.is() )
    1764             :         {
    1765        1386 :             m_xInStream.set( xStream->getInputStream(), uno::UNO_SET_THROW );
    1766        1386 :             m_xOutStream.set( xStream->getOutputStream(), uno::UNO_SET_THROW );
    1767        1386 :             m_xSeekable.set( xStream, uno::UNO_QUERY_THROW );
    1768        1386 :             m_xSeekable->seek( m_nInitPosition );
    1769             : 
    1770        1386 :             m_nInitPosition = 0;
    1771        1386 :             m_bInitOnDemand = false;
    1772        1386 :         }
    1773             :     }
    1774       33340 : }
    1775             : 
    1776           0 : void OWriteStream::CopyToStreamInternally_Impl( const uno::Reference< io::XStream >& xDest )
    1777             : {
    1778           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    1779             : 
    1780           0 :     CheckInitOnDemand();
    1781             : 
    1782           0 :     if ( !m_xInStream.is() )
    1783           0 :         throw uno::RuntimeException();
    1784             : 
    1785           0 :     if ( !m_xSeekable.is() )
    1786           0 :         throw uno::RuntimeException();
    1787             : 
    1788           0 :     uno::Reference< beans::XPropertySet > xDestProps( xDest, uno::UNO_QUERY );
    1789           0 :     if ( !xDestProps.is() )
    1790           0 :         throw uno::RuntimeException(); //TODO
    1791             : 
    1792           0 :     uno::Reference< io::XOutputStream > xDestOutStream = xDest->getOutputStream();
    1793           0 :     if ( !xDestOutStream.is() )
    1794           0 :         throw io::IOException(); // TODO
    1795             : 
    1796           0 :     sal_Int64 nCurPos = m_xSeekable->getPosition();
    1797           0 :     m_xSeekable->seek( 0 );
    1798             : 
    1799           0 :     uno::Exception eThrown;
    1800           0 :     bool bThrown = false;
    1801             :     try {
    1802           0 :         ::comphelper::OStorageHelper::CopyInputToOutput( m_xInStream, xDestOutStream );
    1803             :     }
    1804           0 :     catch ( const uno::Exception& e )
    1805             :     {
    1806           0 :         eThrown = e;
    1807           0 :         bThrown = true;
    1808             :     }
    1809             : 
    1810             :     // position-related section below is critical
    1811             :     // if it fails the stream will become invalid
    1812             :     try {
    1813           0 :         m_xSeekable->seek( nCurPos );
    1814             :     }
    1815           0 :     catch ( const uno::Exception& rException )
    1816             :     {
    1817           0 :         m_pImpl->AddLog( rException.Message );
    1818           0 :         m_pImpl->AddLog( "Quiet exception" );
    1819             : 
    1820             :         // TODO: set the stoream in invalid state or dispose
    1821             :         SAL_WARN( "package.xstor", "The stream become invalid during copiing!" );
    1822           0 :         throw uno::RuntimeException();
    1823             :     }
    1824             : 
    1825           0 :     if ( bThrown )
    1826           0 :         throw eThrown;
    1827             : 
    1828             :     // now the properties can be copied
    1829             :     // the order of the properties setting is not important for StorageStream API
    1830           0 :     OUString aPropName ("Compressed");
    1831           0 :     xDestProps->setPropertyValue( aPropName, getPropertyValue( aPropName ) );
    1832           0 :     if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE || m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
    1833             :     {
    1834           0 :         aPropName = "MediaType";
    1835           0 :         xDestProps->setPropertyValue( aPropName, getPropertyValue( aPropName ) );
    1836             : 
    1837           0 :         if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
    1838             :         {
    1839           0 :             aPropName = "UseCommonStoragePasswordEncryption";
    1840           0 :             xDestProps->setPropertyValue( aPropName, getPropertyValue( aPropName ) );
    1841             :         }
    1842           0 :     }
    1843           0 : }
    1844             : 
    1845      139120 : void OWriteStream::ModifyParentUnlockMutex_Impl( ::osl::ResettableMutexGuard& aGuard )
    1846             : {
    1847      139120 :     if ( m_pImpl->m_pParent )
    1848             :     {
    1849      139120 :         if ( m_pImpl->m_pParent->HasModifiedListener() )
    1850             :         {
    1851        1478 :             uno::Reference< util::XModifiable > xParentModif( (util::XModifiable*)(m_pImpl->m_pParent->m_pAntiImpl) );
    1852        1478 :             aGuard.clear();
    1853        1478 :             xParentModif->setModified( sal_True );
    1854             :         }
    1855             :         else
    1856      137642 :             m_pImpl->m_pParent->m_bIsModified = true;
    1857             :     }
    1858      139120 : }
    1859             : 
    1860      128682 : uno::Any SAL_CALL OWriteStream::queryInterface( const uno::Type& rType )
    1861             :         throw( uno::RuntimeException, std::exception )
    1862             : {
    1863      128682 :     uno::Any aReturn;
    1864             : 
    1865             :     // common interfaces
    1866      257364 :     aReturn <<= ::cppu::queryInterface
    1867             :                 (   rType
    1868             :                     ,   static_cast<lang::XTypeProvider*> ( this )
    1869             :                     ,   static_cast<io::XInputStream*> ( this )
    1870             :                     ,   static_cast<io::XOutputStream*> ( this )
    1871             :                     ,   static_cast<io::XStream*> ( this )
    1872             :                     ,   static_cast<embed::XExtendedStorageStream*> ( this )
    1873             :                     ,   static_cast<io::XSeekable*> ( this )
    1874             :                     ,   static_cast<io::XTruncate*> ( this )
    1875             :                     ,   static_cast<lang::XComponent*> ( this )
    1876      128682 :                     ,   static_cast<beans::XPropertySet*> ( this ) );
    1877             : 
    1878      128682 :     if ( aReturn.hasValue() )
    1879       86770 :         return aReturn ;
    1880             : 
    1881       41912 :     if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
    1882             :     {
    1883       12124 :         aReturn <<= ::cppu::queryInterface
    1884             :                     (   rType
    1885             :                         ,   static_cast<embed::XEncryptionProtectedSource2*> ( this )
    1886        6062 :                         ,   static_cast<embed::XEncryptionProtectedSource*> ( this ) );
    1887             :     }
    1888       35850 :     else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
    1889             :     {
    1890       71700 :         aReturn <<= ::cppu::queryInterface
    1891             :                     (   rType
    1892       35850 :                         ,   static_cast<embed::XRelationshipAccess*> ( this ) );
    1893             :     }
    1894             : 
    1895       41912 :     if ( aReturn.hasValue() )
    1896        8340 :         return aReturn ;
    1897             : 
    1898       33572 :     if ( m_bTransacted )
    1899             :     {
    1900           0 :         aReturn <<= ::cppu::queryInterface
    1901             :                     (   rType
    1902             :                         ,   static_cast<embed::XTransactedObject*> ( this )
    1903           0 :                         ,   static_cast<embed::XTransactionBroadcaster*> ( this ) );
    1904             : 
    1905           0 :         if ( aReturn.hasValue() )
    1906           0 :             return aReturn ;
    1907             :     }
    1908             : 
    1909       33572 :     return OWeakObject::queryInterface( rType );
    1910             : }
    1911             : 
    1912      564268 : void SAL_CALL OWriteStream::acquire() throw()
    1913             : {
    1914      564268 :     OWeakObject::acquire();
    1915      564268 : }
    1916             : 
    1917      564268 : void SAL_CALL OWriteStream::release() throw()
    1918             : {
    1919      564268 :     OWeakObject::release();
    1920      564268 : }
    1921             : 
    1922           0 : uno::Sequence< uno::Type > SAL_CALL OWriteStream::getTypes()
    1923             :         throw( uno::RuntimeException, std::exception )
    1924             : {
    1925           0 :     if ( m_pData->m_pTypeCollection == NULL )
    1926             :     {
    1927           0 :         ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    1928             : 
    1929           0 :         if ( m_pData->m_pTypeCollection == NULL )
    1930             :         {
    1931           0 :             if ( m_bTransacted )
    1932             :             {
    1933           0 :                 if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
    1934             :                 {
    1935             :                     ::cppu::OTypeCollection aTmpCollection
    1936           0 :                                     (   cppu::UnoType<lang::XTypeProvider>::get()
    1937           0 :                                     ,   cppu::UnoType<io::XInputStream>::get()
    1938           0 :                                     ,   cppu::UnoType<io::XOutputStream>::get()
    1939           0 :                                     ,   cppu::UnoType<io::XStream>::get()
    1940           0 :                                     ,   cppu::UnoType<io::XSeekable>::get()
    1941           0 :                                     ,   cppu::UnoType<io::XTruncate>::get()
    1942           0 :                                     ,   cppu::UnoType<lang::XComponent>::get()
    1943           0 :                                     ,   cppu::UnoType<embed::XEncryptionProtectedSource2>::get()
    1944           0 :                                     ,   cppu::UnoType<embed::XEncryptionProtectedSource>::get()
    1945           0 :                                     ,   cppu::UnoType<embed::XExtendedStorageStream>::get()
    1946           0 :                                     ,   cppu::UnoType<embed::XTransactedObject>::get()
    1947           0 :                                     ,   cppu::UnoType<embed::XTransactionBroadcaster>::get());
    1948             : 
    1949             :                     m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
    1950             :                                     (   cppu::UnoType<beans::XPropertySet>::get()
    1951           0 :                                     ,   aTmpCollection.getTypes() );
    1952             :                 }
    1953           0 :                 else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
    1954             :                 {
    1955             :                     m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
    1956             :                                     (   cppu::UnoType<lang::XTypeProvider>::get()
    1957             :                                     ,   cppu::UnoType<io::XInputStream>::get()
    1958             :                                     ,   cppu::UnoType<io::XOutputStream>::get()
    1959             :                                     ,   cppu::UnoType<io::XStream>::get()
    1960             :                                     ,   cppu::UnoType<io::XSeekable>::get()
    1961             :                                     ,   cppu::UnoType<io::XTruncate>::get()
    1962             :                                     ,   cppu::UnoType<lang::XComponent>::get()
    1963             :                                     ,   cppu::UnoType<embed::XRelationshipAccess>::get()
    1964             :                                     ,   cppu::UnoType<embed::XExtendedStorageStream>::get()
    1965             :                                     ,   cppu::UnoType<embed::XTransactedObject>::get()
    1966             :                                     ,   cppu::UnoType<embed::XTransactionBroadcaster>::get()
    1967           0 :                                     ,   cppu::UnoType<beans::XPropertySet>::get());
    1968             :                 }
    1969             :                 else // if ( m_pData->m_nStorageType == embed::StorageFormats::ZIP )
    1970             :                 {
    1971             :                     m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
    1972             :                                     (   cppu::UnoType<lang::XTypeProvider>::get()
    1973             :                                     ,   cppu::UnoType<io::XInputStream>::get()
    1974             :                                     ,   cppu::UnoType<io::XOutputStream>::get()
    1975             :                                     ,   cppu::UnoType<io::XStream>::get()
    1976             :                                     ,   cppu::UnoType<io::XSeekable>::get()
    1977             :                                     ,   cppu::UnoType<io::XTruncate>::get()
    1978             :                                     ,   cppu::UnoType<lang::XComponent>::get()
    1979             :                                     ,   cppu::UnoType<embed::XExtendedStorageStream>::get()
    1980             :                                     ,   cppu::UnoType<embed::XTransactedObject>::get()
    1981             :                                     ,   cppu::UnoType<embed::XTransactionBroadcaster>::get()
    1982           0 :                                     ,   cppu::UnoType<beans::XPropertySet>::get());
    1983             :                 }
    1984             :             }
    1985             :             else
    1986             :             {
    1987           0 :                 if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
    1988             :                 {
    1989             :                     m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
    1990             :                                     (   cppu::UnoType<lang::XTypeProvider>::get()
    1991             :                                     ,   cppu::UnoType<io::XInputStream>::get()
    1992             :                                     ,   cppu::UnoType<io::XOutputStream>::get()
    1993             :                                     ,   cppu::UnoType<io::XStream>::get()
    1994             :                                     ,   cppu::UnoType<io::XSeekable>::get()
    1995             :                                     ,   cppu::UnoType<io::XTruncate>::get()
    1996             :                                     ,   cppu::UnoType<lang::XComponent>::get()
    1997             :                                     ,   cppu::UnoType<embed::XEncryptionProtectedSource2>::get()
    1998             :                                     ,   cppu::UnoType<embed::XEncryptionProtectedSource>::get()
    1999           0 :                                     ,   cppu::UnoType<beans::XPropertySet>::get());
    2000             :                 }
    2001           0 :                 else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
    2002             :                 {
    2003             :                     m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
    2004             :                                     (   cppu::UnoType<lang::XTypeProvider>::get()
    2005             :                                     ,   cppu::UnoType<io::XInputStream>::get()
    2006             :                                     ,   cppu::UnoType<io::XOutputStream>::get()
    2007             :                                     ,   cppu::UnoType<io::XStream>::get()
    2008             :                                     ,   cppu::UnoType<io::XSeekable>::get()
    2009             :                                     ,   cppu::UnoType<io::XTruncate>::get()
    2010             :                                     ,   cppu::UnoType<lang::XComponent>::get()
    2011             :                                     ,   cppu::UnoType<embed::XRelationshipAccess>::get()
    2012           0 :                                     ,   cppu::UnoType<beans::XPropertySet>::get());
    2013             :                 }
    2014             :                 else // if ( m_pData->m_nStorageType == embed::StorageFormats::ZIP )
    2015             :                 {
    2016             :                     m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
    2017             :                                     (   cppu::UnoType<lang::XTypeProvider>::get()
    2018             :                                     ,   cppu::UnoType<io::XInputStream>::get()
    2019             :                                     ,   cppu::UnoType<io::XOutputStream>::get()
    2020             :                                     ,   cppu::UnoType<io::XStream>::get()
    2021             :                                     ,   cppu::UnoType<io::XSeekable>::get()
    2022             :                                     ,   cppu::UnoType<io::XTruncate>::get()
    2023             :                                     ,   cppu::UnoType<lang::XComponent>::get()
    2024           0 :                                     ,   cppu::UnoType<beans::XPropertySet>::get());
    2025             :                 }
    2026             :             }
    2027           0 :         }
    2028             :     }
    2029             : 
    2030           0 :     return m_pData->m_pTypeCollection->getTypes() ;
    2031             : }
    2032             : 
    2033             : namespace { struct lcl_ImplId : public rtl::Static< ::cppu::OImplementationId, lcl_ImplId > {}; }
    2034             : 
    2035           0 : uno::Sequence< sal_Int8 > SAL_CALL OWriteStream::getImplementationId()
    2036             :         throw( uno::RuntimeException, std::exception )
    2037             : {
    2038           0 :     return css::uno::Sequence<sal_Int8>();
    2039             : }
    2040             : 
    2041         222 : sal_Int32 SAL_CALL OWriteStream::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
    2042             :         throw ( io::NotConnectedException,
    2043             :                 io::BufferSizeExceededException,
    2044             :                 io::IOException,
    2045             :                 uno::RuntimeException, std::exception )
    2046             : {
    2047         222 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2048             : 
    2049         222 :     CheckInitOnDemand();
    2050             : 
    2051         222 :     if ( !m_pImpl )
    2052             :     {
    2053             :         SAL_INFO("package.xstor", "Disposed!");
    2054           0 :         throw lang::DisposedException();
    2055             :     }
    2056             : 
    2057         222 :     if ( !m_xInStream.is() )
    2058           0 :         throw io::NotConnectedException();
    2059             : 
    2060         222 :     return m_xInStream->readBytes( aData, nBytesToRead );
    2061             : }
    2062             : 
    2063        1470 : sal_Int32 SAL_CALL OWriteStream::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
    2064             :         throw ( io::NotConnectedException,
    2065             :                 io::BufferSizeExceededException,
    2066             :                 io::IOException,
    2067             :                 uno::RuntimeException, std::exception )
    2068             : {
    2069        1470 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2070             : 
    2071        1470 :     CheckInitOnDemand();
    2072             : 
    2073        1470 :     if ( !m_pImpl )
    2074             :     {
    2075             :         SAL_INFO("package.xstor", "Disposed!");
    2076           0 :         throw lang::DisposedException();
    2077             :     }
    2078             : 
    2079        1470 :     if ( !m_xInStream.is() )
    2080           0 :         throw io::NotConnectedException();
    2081             : 
    2082        1470 :     return m_xInStream->readSomeBytes( aData, nMaxBytesToRead );
    2083             : }
    2084             : 
    2085           0 : void SAL_CALL OWriteStream::skipBytes( sal_Int32 nBytesToSkip )
    2086             :         throw ( io::NotConnectedException,
    2087             :                 io::BufferSizeExceededException,
    2088             :                 io::IOException,
    2089             :                 uno::RuntimeException, std::exception )
    2090             : {
    2091           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2092             : 
    2093           0 :     CheckInitOnDemand();
    2094             : 
    2095           0 :     if ( !m_pImpl )
    2096             :     {
    2097             :         SAL_INFO("package.xstor", "Disposed!");
    2098           0 :         throw lang::DisposedException();
    2099             :     }
    2100             : 
    2101           0 :     if ( !m_xInStream.is() )
    2102           0 :         throw io::NotConnectedException();
    2103             : 
    2104           0 :     m_xInStream->skipBytes( nBytesToSkip );
    2105           0 : }
    2106             : 
    2107           0 : sal_Int32 SAL_CALL OWriteStream::available(  )
    2108             :         throw ( io::NotConnectedException,
    2109             :                 io::IOException,
    2110             :                 uno::RuntimeException, std::exception )
    2111             : {
    2112           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2113             : 
    2114           0 :     CheckInitOnDemand();
    2115             : 
    2116           0 :     if ( !m_pImpl )
    2117             :     {
    2118             :         SAL_INFO("package.xstor", "Disposed!");
    2119           0 :         throw lang::DisposedException();
    2120             :     }
    2121             : 
    2122           0 :     if ( !m_xInStream.is() )
    2123           0 :         throw io::NotConnectedException();
    2124             : 
    2125           0 :     return m_xInStream->available();
    2126             : 
    2127             : }
    2128             : 
    2129           4 : void SAL_CALL OWriteStream::closeInput(  )
    2130             :         throw ( io::NotConnectedException,
    2131             :                 io::IOException,
    2132             :                 uno::RuntimeException, std::exception )
    2133             : {
    2134           4 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2135             : 
    2136           4 :     if ( !m_pImpl )
    2137             :     {
    2138             :         SAL_INFO("package.xstor", "Disposed!");
    2139           0 :         throw lang::DisposedException();
    2140             :     }
    2141             : 
    2142           4 :     if ( !m_bInitOnDemand && ( m_bInStreamDisconnected || !m_xInStream.is() ) )
    2143           0 :         throw io::NotConnectedException();
    2144             : 
    2145             :     // the input part of the stream stays open for internal purposes ( to allow reading during copiing )
    2146             :     // since it can not be reopened until output part is closed, it will be closed with output part.
    2147           4 :     m_bInStreamDisconnected = true;
    2148             :     // m_xInStream->closeInput();
    2149             :     // m_xInStream = uno::Reference< io::XInputStream >();
    2150             : 
    2151           4 :     if ( !m_xOutStream.is() )
    2152           0 :         dispose();
    2153           4 : }
    2154             : 
    2155        1832 : uno::Reference< io::XInputStream > SAL_CALL OWriteStream::getInputStream()
    2156             :         throw ( uno::RuntimeException, std::exception )
    2157             : {
    2158        1832 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2159             : 
    2160        1832 :     if ( !m_pImpl )
    2161             :     {
    2162             :         SAL_INFO("package.xstor", "Disposed!");
    2163           0 :         throw lang::DisposedException();
    2164             :     }
    2165             : 
    2166        1832 :     if ( !m_bInitOnDemand && ( m_bInStreamDisconnected || !m_xInStream.is() ) )
    2167           0 :         return uno::Reference< io::XInputStream >();
    2168             : 
    2169        1832 :     return uno::Reference< io::XInputStream >( static_cast< io::XInputStream* >( this ), uno::UNO_QUERY );
    2170             : }
    2171             : 
    2172       11952 : uno::Reference< io::XOutputStream > SAL_CALL OWriteStream::getOutputStream()
    2173             :         throw ( uno::RuntimeException, std::exception )
    2174             : {
    2175       11952 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2176             : 
    2177             :     try
    2178             :     {
    2179       11952 :         CheckInitOnDemand();
    2180             :     }
    2181           0 :     catch( const io::IOException& r )
    2182             :     {
    2183             :         throw lang::WrappedTargetRuntimeException("OWriteStream::getOutputStream: Could not create backing temp file",
    2184           0 :                 static_cast < OWeakObject * > ( this ), makeAny ( r ) );
    2185             :     }
    2186             : 
    2187       11952 :     if ( !m_pImpl )
    2188             :     {
    2189             :         SAL_INFO("package.xstor", "Disposed!");
    2190           0 :         throw lang::DisposedException();
    2191             :     }
    2192             : 
    2193       11952 :     if ( !m_xOutStream.is() )
    2194           0 :         return uno::Reference< io::XOutputStream >();
    2195             : 
    2196       11952 :     return uno::Reference< io::XOutputStream >( static_cast< io::XOutputStream* >( this ), uno::UNO_QUERY );
    2197             : }
    2198             : 
    2199      103328 : void SAL_CALL OWriteStream::writeBytes( const uno::Sequence< sal_Int8 >& aData )
    2200             :         throw ( io::NotConnectedException,
    2201             :                 io::BufferSizeExceededException,
    2202             :                 io::IOException,
    2203             :                 uno::RuntimeException, std::exception )
    2204             : {
    2205      103328 :     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2206             : 
    2207             :     // the write method makes initialization itself, since it depends from the aData length
    2208             :     // NO CheckInitOnDemand()!
    2209             : 
    2210      103328 :     if ( !m_pImpl )
    2211             :     {
    2212             :         SAL_INFO("package.xstor", "Disposed!");
    2213           0 :         throw lang::DisposedException();
    2214             :     }
    2215             : 
    2216      103328 :     if ( !m_bInitOnDemand )
    2217             :     {
    2218      103326 :         if ( !m_xOutStream.is() || !m_xSeekable.is())
    2219           0 :             throw io::NotConnectedException();
    2220             : 
    2221      103326 :         if ( m_pImpl->m_xCacheStream.is() )
    2222             :         {
    2223             :             // check whether the cache should be turned off
    2224       83682 :             sal_Int64 nPos = m_xSeekable->getPosition();
    2225       83682 :             if ( nPos + aData.getLength() > MAX_STORCACHE_SIZE )
    2226             :             {
    2227             :                 // disconnect the cache and copy the data to the temporary file
    2228         452 :                 m_xSeekable->seek( 0 );
    2229             : 
    2230             :                 // it is enough to copy the cached stream, the cache should already contain everything
    2231         452 :                 if ( !m_pImpl->GetFilledTempFileIfNo( m_xInStream ).isEmpty() )
    2232             :                 {
    2233         452 :                     DeInit();
    2234             :                     // the last position is known and it is differs from the current stream position
    2235         452 :                     m_nInitPosition = nPos;
    2236             :                 }
    2237             :             }
    2238             :         }
    2239             :     }
    2240             : 
    2241      103328 :     if ( m_bInitOnDemand )
    2242             :     {
    2243             :         SAL_INFO( "package.xstor", "package (mv76033) OWriteStream::CheckInitOnDemand, initializing" );
    2244         454 :         uno::Reference< io::XStream > xStream = m_pImpl->GetTempFileAsStream();
    2245         454 :         if ( xStream.is() )
    2246             :         {
    2247         454 :             m_xInStream.set( xStream->getInputStream(), uno::UNO_SET_THROW );
    2248         454 :             m_xOutStream.set( xStream->getOutputStream(), uno::UNO_SET_THROW );
    2249         454 :             m_xSeekable.set( xStream, uno::UNO_QUERY_THROW );
    2250         454 :             m_xSeekable->seek( m_nInitPosition );
    2251             : 
    2252         454 :             m_nInitPosition = 0;
    2253         454 :             m_bInitOnDemand = false;
    2254         454 :         }
    2255             :     }
    2256             : 
    2257      103328 :     if ( !m_xOutStream.is() )
    2258           0 :         throw io::NotConnectedException();
    2259             : 
    2260      103328 :     m_xOutStream->writeBytes( aData );
    2261      103328 :     m_pImpl->m_bHasDataToFlush = true;
    2262             : 
    2263      103328 :     ModifyParentUnlockMutex_Impl( aGuard );
    2264      103328 : }
    2265             : 
    2266        4112 : void SAL_CALL OWriteStream::flush()
    2267             :         throw ( io::NotConnectedException,
    2268             :                 io::BufferSizeExceededException,
    2269             :                 io::IOException,
    2270             :                 uno::RuntimeException, std::exception )
    2271             : {
    2272             :     // In case stream is flushed its current version becomes visible
    2273             :     // to the parent storage. Usually parent storage flushes the stream
    2274             :     // during own commit but a user can explicitly flush the stream
    2275             :     // so the changes will be available through cloning functionality.
    2276             : 
    2277        4112 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2278             : 
    2279        4112 :     if ( !m_pImpl )
    2280             :     {
    2281             :         SAL_INFO("package.xstor", "Disposed!");
    2282           0 :         throw lang::DisposedException();
    2283             :     }
    2284             : 
    2285        4112 :     if ( !m_bInitOnDemand )
    2286             :     {
    2287        3960 :         if ( !m_xOutStream.is() )
    2288           0 :             throw io::NotConnectedException();
    2289             : 
    2290        3960 :         m_xOutStream->flush();
    2291        3960 :         m_pImpl->Commit();
    2292        4112 :     }
    2293        4112 : }
    2294             : 
    2295       21702 : void OWriteStream::CloseOutput_Impl()
    2296             : {
    2297             :     // all the checks must be done in calling method
    2298             : 
    2299       21702 :     m_xOutStream->closeOutput();
    2300       21702 :     m_xOutStream = uno::Reference< io::XOutputStream >();
    2301             : 
    2302       21702 :     if ( !m_bInitOnDemand )
    2303             :     {
    2304             :         // after the stream is disposed it can be commited
    2305             :         // so transport correct size property
    2306       21702 :         if ( !m_xSeekable.is() )
    2307           0 :             throw uno::RuntimeException();
    2308             : 
    2309       93534 :         for ( sal_Int32 nInd = 0; nInd < m_pImpl->m_aProps.getLength(); nInd++ )
    2310             :         {
    2311       71832 :             if ( m_pImpl->m_aProps[nInd].Name == "Size" )
    2312       21702 :                 m_pImpl->m_aProps[nInd].Value <<= m_xSeekable->getLength();
    2313             :         }
    2314             :     }
    2315       21702 : }
    2316             : 
    2317       12394 : void SAL_CALL OWriteStream::closeOutput()
    2318             :         throw ( io::NotConnectedException,
    2319             :                 io::BufferSizeExceededException,
    2320             :                 io::IOException,
    2321             :                 uno::RuntimeException, std::exception )
    2322             : {
    2323       12394 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2324             : 
    2325       12394 :     CheckInitOnDemand();
    2326             : 
    2327       12392 :     if ( !m_pImpl )
    2328             :     {
    2329             :         SAL_INFO("package.xstor", "Disposed!");
    2330           0 :         throw lang::DisposedException();
    2331             :     }
    2332             : 
    2333       12392 :     if ( !m_xOutStream.is() )
    2334           0 :         throw io::NotConnectedException();
    2335             : 
    2336       12392 :     CloseOutput_Impl();
    2337             : 
    2338       12392 :     if ( m_bInStreamDisconnected || !m_xInStream.is() )
    2339           2 :         dispose();
    2340       12392 : }
    2341             : 
    2342        5236 : void SAL_CALL OWriteStream::seek( sal_Int64 location )
    2343             :         throw ( lang::IllegalArgumentException,
    2344             :                 io::IOException,
    2345             :                 uno::RuntimeException, std::exception )
    2346             : {
    2347        5236 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2348             : 
    2349        5236 :     CheckInitOnDemand();
    2350             : 
    2351        5236 :     if ( !m_pImpl )
    2352             :     {
    2353             :         SAL_INFO("package.xstor", "Disposed!");
    2354           0 :         throw lang::DisposedException();
    2355             :     }
    2356             : 
    2357        5236 :     if ( !m_xSeekable.is() )
    2358           0 :         throw uno::RuntimeException();
    2359             : 
    2360        5236 :     m_xSeekable->seek( location );
    2361        5236 : }
    2362             : 
    2363           0 : sal_Int64 SAL_CALL OWriteStream::getPosition()
    2364             :         throw ( io::IOException,
    2365             :                 uno::RuntimeException, std::exception)
    2366             : {
    2367           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2368             : 
    2369           0 :     CheckInitOnDemand();
    2370             : 
    2371           0 :     if ( !m_pImpl )
    2372             :     {
    2373             :         SAL_INFO("package.xstor", "Disposed!");
    2374           0 :         throw lang::DisposedException();
    2375             :     }
    2376             : 
    2377           0 :     if ( !m_xSeekable.is() )
    2378           0 :         throw uno::RuntimeException();
    2379             : 
    2380           0 :     return m_xSeekable->getPosition();
    2381             : }
    2382             : 
    2383        1998 : sal_Int64 SAL_CALL OWriteStream::getLength()
    2384             :         throw ( io::IOException,
    2385             :                 uno::RuntimeException, std::exception )
    2386             : {
    2387        1998 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2388             : 
    2389        1998 :     CheckInitOnDemand();
    2390             : 
    2391        1998 :     if ( !m_pImpl )
    2392             :     {
    2393             :         SAL_INFO("package.xstor", "Disposed!");
    2394           0 :         throw lang::DisposedException();
    2395             :     }
    2396             : 
    2397        1998 :     if ( !m_xSeekable.is() )
    2398           0 :         throw uno::RuntimeException();
    2399             : 
    2400        1998 :     return m_xSeekable->getLength();
    2401             : }
    2402             : 
    2403          70 : void SAL_CALL OWriteStream::truncate()
    2404             :         throw ( io::IOException,
    2405             :                 uno::RuntimeException, std::exception )
    2406             : {
    2407          70 :     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2408             : 
    2409          70 :     CheckInitOnDemand();
    2410             : 
    2411          70 :     if ( !m_pImpl )
    2412             :     {
    2413             :         SAL_INFO("package.xstor", "Disposed!");
    2414           0 :         throw lang::DisposedException();
    2415             :     }
    2416             : 
    2417          70 :     if ( !m_xOutStream.is() )
    2418           0 :         throw uno::RuntimeException();
    2419             : 
    2420         140 :     uno::Reference< io::XTruncate > xTruncate( m_xOutStream, uno::UNO_QUERY );
    2421             : 
    2422          70 :     if ( !xTruncate.is() )
    2423             :     {
    2424             :         SAL_WARN( "package.xstor", "The output stream must support XTruncate interface!" );
    2425           0 :         throw uno::RuntimeException();
    2426             :     }
    2427             : 
    2428          70 :     xTruncate->truncate();
    2429             : 
    2430          70 :     m_pImpl->m_bHasDataToFlush = true;
    2431             : 
    2432         140 :     ModifyParentUnlockMutex_Impl( aGuard );
    2433          70 : }
    2434             : 
    2435       25548 : void SAL_CALL OWriteStream::dispose()
    2436             :         throw ( uno::RuntimeException, std::exception )
    2437             : {
    2438             :     // should be an internal method since it can be called only from parent storage
    2439             :     {
    2440       25548 :         ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2441             : 
    2442       25548 :         if ( !m_pImpl )
    2443             :         {
    2444             :             SAL_INFO("package.xstor", "Disposed!");
    2445           0 :             throw lang::DisposedException();
    2446             :         }
    2447             : 
    2448       25548 :         if ( m_xOutStream.is() )
    2449        9310 :             CloseOutput_Impl();
    2450             : 
    2451       25548 :         if ( m_xInStream.is() )
    2452             :         {
    2453       21094 :             m_xInStream->closeInput();
    2454       21094 :             m_xInStream = uno::Reference< io::XInputStream >();
    2455             :         }
    2456             : 
    2457       25548 :         m_xSeekable = uno::Reference< io::XSeekable >();
    2458             : 
    2459       25548 :         m_pImpl->m_pAntiImpl = NULL;
    2460             : 
    2461       25548 :         if ( !m_bInitOnDemand )
    2462             :         {
    2463             :             try
    2464             :             {
    2465       21094 :                 if ( !m_bTransacted )
    2466             :                 {
    2467       21094 :                     m_pImpl->Commit();
    2468             :                 }
    2469             :                 else
    2470             :                 {
    2471             :                     // throw away all the changes
    2472           0 :                     m_pImpl->Revert();
    2473             :                 }
    2474             :             }
    2475           0 :             catch( const uno::Exception& rException )
    2476             :             {
    2477           0 :                 m_pImpl->AddLog( rException.Message );
    2478           0 :                 m_pImpl->AddLog( "Rethrow" );
    2479             : 
    2480           0 :                 uno::Any aCaught( ::cppu::getCaughtException() );
    2481             :                 throw lang::WrappedTargetRuntimeException("Can not commit/revert the storage!",
    2482             :                                                 static_cast< OWeakObject* >( this ),
    2483           0 :                                                 aCaught );
    2484             :             }
    2485             :         }
    2486             : 
    2487       25548 :         m_pImpl = NULL;
    2488             :     }
    2489             : 
    2490             :     // the listener might try to get rid of parent storage, and the storage would delete this object;
    2491             :     // for now the listener is just notified at the end of the method to workaround the problem
    2492             :     // in future a more elegant way should be found
    2493             : 
    2494       25548 :        lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
    2495       25548 :     m_pData->m_aListenersContainer.disposeAndClear( aSource );
    2496       25548 : }
    2497             : 
    2498           0 : void SAL_CALL OWriteStream::addEventListener(
    2499             :             const uno::Reference< lang::XEventListener >& xListener )
    2500             :         throw ( uno::RuntimeException, std::exception )
    2501             : {
    2502           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2503             : 
    2504           0 :     if ( !m_pImpl )
    2505             :     {
    2506             :         SAL_INFO("package.xstor", "Disposed!");
    2507           0 :         throw lang::DisposedException();
    2508             :     }
    2509             : 
    2510           0 :     m_pData->m_aListenersContainer.addInterface( cppu::UnoType<lang::XEventListener>::get(),
    2511           0 :                                                  xListener );
    2512           0 : }
    2513             : 
    2514           0 : void SAL_CALL OWriteStream::removeEventListener(
    2515             :             const uno::Reference< lang::XEventListener >& xListener )
    2516             :         throw ( uno::RuntimeException, std::exception )
    2517             : {
    2518           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2519             : 
    2520           0 :     if ( !m_pImpl )
    2521             :     {
    2522             :         SAL_INFO("package.xstor", "Disposed!");
    2523           0 :         throw lang::DisposedException();
    2524             :     }
    2525             : 
    2526           0 :     m_pData->m_aListenersContainer.removeInterface( cppu::UnoType<lang::XEventListener>::get(),
    2527           0 :                                                     xListener );
    2528           0 : }
    2529             : 
    2530           0 : void SAL_CALL OWriteStream::setEncryptionPassword( const OUString& aPass )
    2531             :     throw ( uno::RuntimeException,
    2532             :             io::IOException, std::exception )
    2533             : {
    2534           0 :     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2535             : 
    2536           0 :     CheckInitOnDemand();
    2537             : 
    2538           0 :     if ( !m_pImpl )
    2539             :     {
    2540             :         SAL_INFO("package.xstor", "Disposed!");
    2541           0 :         throw lang::DisposedException();
    2542             :     }
    2543             : 
    2544             :     OSL_ENSURE( m_pImpl->m_xPackageStream.is(), "No package stream is set!\n" );
    2545             : 
    2546           0 :     m_pImpl->SetEncrypted( ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
    2547             : 
    2548           0 :     ModifyParentUnlockMutex_Impl( aGuard );
    2549           0 : }
    2550             : 
    2551           0 : void SAL_CALL OWriteStream::removeEncryption()
    2552             :     throw ( uno::RuntimeException,
    2553             :             io::IOException, std::exception )
    2554             : {
    2555           0 :     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2556             : 
    2557           0 :     CheckInitOnDemand();
    2558             : 
    2559           0 :     if ( !m_pImpl )
    2560             :     {
    2561             :         SAL_INFO("package.xstor", "Disposed!");
    2562           0 :         throw lang::DisposedException();
    2563             :     }
    2564             : 
    2565             :     OSL_ENSURE( m_pImpl->m_xPackageStream.is(), "No package stream is set!\n" );
    2566             : 
    2567           0 :     m_pImpl->SetDecrypted();
    2568             : 
    2569           0 :     ModifyParentUnlockMutex_Impl( aGuard );
    2570           0 : }
    2571             : 
    2572           0 : void SAL_CALL OWriteStream::setEncryptionData( const uno::Sequence< beans::NamedValue >& aEncryptionData )
    2573             :     throw (io::IOException, uno::RuntimeException, std::exception)
    2574             : {
    2575           0 :     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2576             : 
    2577           0 :     CheckInitOnDemand();
    2578             : 
    2579           0 :     if ( !m_pImpl )
    2580             :     {
    2581             :         SAL_INFO("package.xstor", "Disposed!");
    2582           0 :         throw lang::DisposedException();
    2583             :     }
    2584             : 
    2585             :     OSL_ENSURE( m_pImpl->m_xPackageStream.is(), "No package stream is set!\n" );
    2586             : 
    2587           0 :     m_pImpl->SetEncrypted( aEncryptionData );
    2588             : 
    2589           0 :     ModifyParentUnlockMutex_Impl( aGuard );
    2590           0 : }
    2591             : 
    2592          76 : sal_Bool SAL_CALL OWriteStream::hasEncryptionData()
    2593             :     throw (uno::RuntimeException, std::exception)
    2594             : {
    2595          76 :     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2596             : 
    2597          76 :     if (!m_pImpl)
    2598           0 :         return false;
    2599             : 
    2600          76 :     bool bRet = false;
    2601             : 
    2602             :     try
    2603             :     {
    2604          76 :         bRet = m_pImpl->IsEncrypted();
    2605             : 
    2606          76 :         if (!bRet && m_pImpl->m_bUseCommonEncryption && m_pImpl->m_pParent)
    2607          76 :             bRet = m_pImpl->m_pParent->m_bHasCommonEncryptionData;
    2608             :     }
    2609           0 :     catch( const uno::RuntimeException& rRuntimeException )
    2610             :     {
    2611           0 :         m_pImpl->AddLog( rRuntimeException.Message );
    2612           0 :         m_pImpl->AddLog( "Rethrow" );
    2613           0 :         throw;
    2614             :     }
    2615           0 :     catch( const uno::Exception& rException )
    2616             :     {
    2617           0 :         m_pImpl->AddLog( rException.Message );
    2618           0 :         m_pImpl->AddLog( "Rethrow" );
    2619             : 
    2620           0 :         uno::Any aCaught( ::cppu::getCaughtException() );
    2621             :         throw lang::WrappedTargetRuntimeException( "Problems on hasEncryptionData!",
    2622             :                                   static_cast< ::cppu::OWeakObject* >( this ),
    2623           0 :                                   aCaught );
    2624             :     }
    2625             : 
    2626          76 :     return bRet;
    2627             : }
    2628             : 
    2629           0 : sal_Bool SAL_CALL OWriteStream::hasByID(  const OUString& sID )
    2630             :         throw ( io::IOException,
    2631             :                 uno::RuntimeException, std::exception )
    2632             : {
    2633           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2634             : 
    2635           0 :     if ( !m_pImpl )
    2636             :     {
    2637             :         SAL_INFO("package.xstor", "Disposed!");
    2638           0 :         throw lang::DisposedException();
    2639             :     }
    2640             : 
    2641           0 :     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
    2642           0 :         throw uno::RuntimeException();
    2643             : 
    2644             :     try
    2645             :     {
    2646           0 :         getRelationshipByID( sID );
    2647           0 :         return sal_True;
    2648             :     }
    2649           0 :     catch( const container::NoSuchElementException& rNoSuchElementException )
    2650             :     {
    2651           0 :         m_pImpl->AddLog( rNoSuchElementException.Message );
    2652           0 :         m_pImpl->AddLog( "No Element" );
    2653             :     }
    2654             : 
    2655           0 :     return sal_False;
    2656             : }
    2657             : 
    2658           0 : OUString SAL_CALL OWriteStream::getTargetByID(  const OUString& sID  )
    2659             :         throw ( container::NoSuchElementException,
    2660             :                 io::IOException,
    2661             :                 uno::RuntimeException, std::exception )
    2662             : {
    2663           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2664             : 
    2665           0 :     if ( !m_pImpl )
    2666             :     {
    2667             :         SAL_INFO("package.xstor", "Disposed!");
    2668           0 :         throw lang::DisposedException();
    2669             :     }
    2670             : 
    2671           0 :     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
    2672           0 :         throw uno::RuntimeException();
    2673             : 
    2674           0 :     uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
    2675           0 :     for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
    2676           0 :         if ( aSeq[nInd].First == "Target" )
    2677           0 :             return aSeq[nInd].Second;
    2678             : 
    2679           0 :     return OUString();
    2680             : }
    2681             : 
    2682           0 : OUString SAL_CALL OWriteStream::getTypeByID(  const OUString& sID  )
    2683             :         throw ( container::NoSuchElementException,
    2684             :                 io::IOException,
    2685             :                 uno::RuntimeException, std::exception )
    2686             : {
    2687           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2688             : 
    2689           0 :     if ( !m_pImpl )
    2690             :     {
    2691             :         SAL_INFO("package.xstor", "Disposed!");
    2692           0 :         throw lang::DisposedException();
    2693             :     }
    2694             : 
    2695           0 :     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
    2696           0 :         throw uno::RuntimeException();
    2697             : 
    2698           0 :     uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
    2699           0 :     for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
    2700           0 :         if ( aSeq[nInd].First == "Type" )
    2701           0 :             return aSeq[nInd].Second;
    2702             : 
    2703           0 :     return OUString();
    2704             : }
    2705             : 
    2706           0 : uno::Sequence< beans::StringPair > SAL_CALL OWriteStream::getRelationshipByID(  const OUString& sID  )
    2707             :         throw ( container::NoSuchElementException,
    2708             :                 io::IOException,
    2709             :                 uno::RuntimeException, std::exception )
    2710             : {
    2711           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2712             : 
    2713           0 :     if ( !m_pImpl )
    2714             :     {
    2715             :         SAL_INFO("package.xstor", "Disposed!");
    2716           0 :         throw lang::DisposedException();
    2717             :     }
    2718             : 
    2719           0 :     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
    2720           0 :         throw uno::RuntimeException();
    2721             : 
    2722             :     // TODO/LATER: in future the unification of the ID could be checked
    2723           0 :     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
    2724           0 :     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
    2725           0 :         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
    2726           0 :             if ( aSeq[nInd1][nInd2].First == "Id" )
    2727             :             {
    2728           0 :                 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
    2729           0 :                     return aSeq[nInd1];
    2730           0 :                 break;
    2731             :             }
    2732             : 
    2733           0 :     throw container::NoSuchElementException();
    2734             : }
    2735             : 
    2736           0 : uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OWriteStream::getRelationshipsByType(  const OUString& sType  )
    2737             :         throw ( io::IOException,
    2738             :                 uno::RuntimeException, std::exception )
    2739             : {
    2740           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2741             : 
    2742           0 :     if ( !m_pImpl )
    2743             :     {
    2744             :         SAL_INFO("package.xstor", "Disposed!");
    2745           0 :         throw lang::DisposedException();
    2746             :     }
    2747             : 
    2748           0 :     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
    2749           0 :         throw uno::RuntimeException();
    2750             : 
    2751           0 :     uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
    2752           0 :     sal_Int32 nEntriesNum = 0;
    2753             : 
    2754             :     // TODO/LATER: in future the unification of the ID could be checked
    2755           0 :     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
    2756           0 :     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
    2757           0 :         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
    2758           0 :             if ( aSeq[nInd1][nInd2].First == "Type" )
    2759             :             {
    2760           0 :                 if ( aSeq[nInd1][nInd2].Second.equals( sType ) )
    2761             :                 {
    2762           0 :                     aResult.realloc( nEntriesNum );
    2763           0 :                     aResult[nEntriesNum-1] = aSeq[nInd1];
    2764             :                 }
    2765           0 :                 break;
    2766             :             }
    2767             : 
    2768           0 :     return aResult;
    2769             : }
    2770             : 
    2771        8264 : uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OWriteStream::getAllRelationships()
    2772             :         throw (io::IOException, uno::RuntimeException, std::exception)
    2773             : {
    2774        8264 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2775             : 
    2776        8264 :     if ( !m_pImpl )
    2777             :     {
    2778             :         SAL_INFO("package.xstor", "Disposed!");
    2779           0 :         throw lang::DisposedException();
    2780             :     }
    2781             : 
    2782        8264 :     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
    2783           0 :         throw uno::RuntimeException();
    2784             : 
    2785        8264 :     return m_pImpl->GetAllRelationshipsIfAny();
    2786             : }
    2787             : 
    2788        8264 : void SAL_CALL OWriteStream::insertRelationshipByID(  const OUString& sID, const uno::Sequence< beans::StringPair >& aEntry, sal_Bool bReplace  )
    2789             :         throw ( container::ElementExistException,
    2790             :                 io::IOException,
    2791             :                 uno::RuntimeException, std::exception )
    2792             : {
    2793        8264 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2794             : 
    2795        8264 :     if ( !m_pImpl )
    2796             :     {
    2797             :         SAL_INFO("package.xstor", "Disposed!");
    2798           0 :         throw lang::DisposedException();
    2799             :     }
    2800             : 
    2801        8264 :     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
    2802           0 :         throw uno::RuntimeException();
    2803             : 
    2804       16528 :     OUString aIDTag( "Id" );
    2805             : 
    2806        8264 :     sal_Int32 nIDInd = -1;
    2807             : 
    2808             :     // TODO/LATER: in future the unification of the ID could be checked
    2809       16528 :     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
    2810      237768 :     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
    2811      229504 :         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
    2812      229504 :             if ( aSeq[nInd1][nInd2].First.equals( aIDTag ) )
    2813             :             {
    2814      229504 :                 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
    2815           0 :                     nIDInd = nInd1;
    2816             : 
    2817      229504 :                 break;
    2818             :             }
    2819             : 
    2820        8264 :     if ( nIDInd == -1 || bReplace )
    2821             :     {
    2822        8264 :         if ( nIDInd == -1 )
    2823             :         {
    2824        8264 :             nIDInd = aSeq.getLength();
    2825        8264 :             aSeq.realloc( nIDInd + 1 );
    2826             :         }
    2827             : 
    2828        8264 :         aSeq[nIDInd].realloc( aEntry.getLength() + 1 );
    2829             : 
    2830        8264 :         aSeq[nIDInd][0].First = aIDTag;
    2831        8264 :         aSeq[nIDInd][0].Second = sID;
    2832        8264 :         sal_Int32 nIndTarget = 1;
    2833       49988 :         for ( sal_Int32 nIndOrig = 0;
    2834       24994 :               nIndOrig < aEntry.getLength();
    2835             :               nIndOrig++ )
    2836             :         {
    2837       16730 :             if ( !aEntry[nIndOrig].First.equals( aIDTag ) )
    2838       16730 :                 aSeq[nIDInd][nIndTarget++] = aEntry[nIndOrig];
    2839             :         }
    2840             : 
    2841        8264 :         aSeq[nIDInd].realloc( nIndTarget );
    2842             :     }
    2843             :     else
    2844           0 :         throw container::ElementExistException(); // TODO
    2845             : 
    2846        8264 :     m_pImpl->m_aNewRelInfo = aSeq;
    2847        8264 :     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
    2848       16528 :     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
    2849        8264 : }
    2850             : 
    2851           0 : void SAL_CALL OWriteStream::removeRelationshipByID(  const OUString& sID  )
    2852             :         throw ( container::NoSuchElementException,
    2853             :                 io::IOException,
    2854             :                 uno::RuntimeException, std::exception )
    2855             : {
    2856           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2857             : 
    2858           0 :     if ( !m_pImpl )
    2859             :     {
    2860             :         SAL_INFO("package.xstor", "Disposed!");
    2861           0 :         throw lang::DisposedException();
    2862             :     }
    2863             : 
    2864           0 :     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
    2865           0 :         throw uno::RuntimeException();
    2866             : 
    2867           0 :     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
    2868           0 :     for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
    2869           0 :         for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
    2870           0 :             if ( aSeq[nInd1][nInd2].First == "Id" )
    2871             :             {
    2872           0 :                 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
    2873             :                 {
    2874           0 :                     sal_Int32 nLength = aSeq.getLength();
    2875           0 :                     aSeq[nInd1] = aSeq[nLength-1];
    2876           0 :                     aSeq.realloc( nLength - 1 );
    2877             : 
    2878           0 :                     m_pImpl->m_aNewRelInfo = aSeq;
    2879           0 :                     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
    2880           0 :                     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
    2881             : 
    2882             :                     // TODO/LATER: in future the unification of the ID could be checked
    2883           0 :                     return;
    2884             :                 }
    2885             : 
    2886           0 :                 break;
    2887             :             }
    2888             : 
    2889           0 :     throw container::NoSuchElementException();
    2890             : }
    2891             : 
    2892           0 : void SAL_CALL OWriteStream::insertRelationships(  const uno::Sequence< uno::Sequence< beans::StringPair > >& aEntries, sal_Bool bReplace  )
    2893             :         throw ( container::ElementExistException,
    2894             :                 io::IOException,
    2895             :                 uno::RuntimeException, std::exception )
    2896             : {
    2897           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2898             : 
    2899           0 :     if ( !m_pImpl )
    2900             :     {
    2901             :         SAL_INFO("package.xstor", "Disposed!");
    2902           0 :         throw lang::DisposedException();
    2903             :     }
    2904             : 
    2905           0 :     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
    2906           0 :         throw uno::RuntimeException();
    2907             : 
    2908           0 :     OUString aIDTag( "Id" );
    2909           0 :     uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
    2910           0 :     uno::Sequence< uno::Sequence< beans::StringPair > > aResultSeq( aSeq.getLength() + aEntries.getLength() );
    2911           0 :     sal_Int32 nResultInd = 0;
    2912             : 
    2913           0 :     for ( sal_Int32 nIndTarget1 = 0; nIndTarget1 < aSeq.getLength(); nIndTarget1++ )
    2914           0 :         for ( sal_Int32 nIndTarget2 = 0; nIndTarget2 < aSeq[nIndTarget1].getLength(); nIndTarget2++ )
    2915           0 :             if ( aSeq[nIndTarget1][nIndTarget2].First.equals( aIDTag ) )
    2916             :             {
    2917           0 :                 sal_Int32 nIndSourceSame = -1;
    2918             : 
    2919           0 :                 for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
    2920           0 :                     for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
    2921             :                     {
    2922           0 :                         if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
    2923             :                         {
    2924           0 :                             if ( aEntries[nIndSource1][nIndSource2].Second.equals( aSeq[nIndTarget1][nIndTarget2].Second ) )
    2925             :                             {
    2926           0 :                                 if ( !bReplace )
    2927           0 :                                     throw container::ElementExistException();
    2928             : 
    2929           0 :                                 nIndSourceSame = nIndSource1;
    2930             :                             }
    2931             : 
    2932           0 :                             break;
    2933             :                         }
    2934             :                     }
    2935             : 
    2936           0 :                 if ( nIndSourceSame == -1 )
    2937             :                 {
    2938             :                     // no such element in the provided sequence
    2939           0 :                     aResultSeq[nResultInd++] = aSeq[nIndTarget1];
    2940             :                 }
    2941             : 
    2942           0 :                 break;
    2943             :             }
    2944             : 
    2945           0 :     for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
    2946             :     {
    2947           0 :         aResultSeq[nResultInd].realloc( aEntries[nIndSource1].getLength() );
    2948           0 :         bool bHasID = false;
    2949           0 :         sal_Int32 nResInd2 = 1;
    2950             : 
    2951           0 :         for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
    2952           0 :             if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
    2953             :             {
    2954           0 :                 aResultSeq[nResultInd][0] = aEntries[nIndSource1][nIndSource2];
    2955           0 :                 bHasID = true;
    2956             :             }
    2957           0 :             else if ( nResInd2 < aResultSeq[nResultInd].getLength() )
    2958           0 :                 aResultSeq[nResultInd][nResInd2++] = aEntries[nIndSource1][nIndSource2];
    2959             :             else
    2960           0 :                 throw io::IOException(); // TODO: illegal relation ( no ID )
    2961             : 
    2962           0 :         if ( !bHasID )
    2963           0 :             throw io::IOException(); // TODO: illegal relations
    2964             : 
    2965           0 :         nResultInd++;
    2966             :     }
    2967             : 
    2968           0 :     aResultSeq.realloc( nResultInd );
    2969           0 :     m_pImpl->m_aNewRelInfo = aResultSeq;
    2970           0 :     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
    2971           0 :     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
    2972           0 : }
    2973             : 
    2974           0 : void SAL_CALL OWriteStream::clearRelationships()
    2975             :         throw ( io::IOException,
    2976             :                 uno::RuntimeException, std::exception )
    2977             : {
    2978           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2979             : 
    2980           0 :     if ( !m_pImpl )
    2981             :     {
    2982             :         SAL_INFO("package.xstor", "Disposed!");
    2983           0 :         throw lang::DisposedException();
    2984             :     }
    2985             : 
    2986           0 :     if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
    2987           0 :         throw uno::RuntimeException();
    2988             : 
    2989           0 :     m_pImpl->m_aNewRelInfo.realloc( 0 );
    2990           0 :     m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
    2991           0 :     m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
    2992           0 : }
    2993             : 
    2994       21162 : uno::Reference< beans::XPropertySetInfo > SAL_CALL OWriteStream::getPropertySetInfo()
    2995             :         throw ( uno::RuntimeException, std::exception )
    2996             : {
    2997       21162 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    2998             : 
    2999             :     //TODO:
    3000       21162 :     return uno::Reference< beans::XPropertySetInfo >();
    3001             : }
    3002             : 
    3003       35722 : void SAL_CALL OWriteStream::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
    3004             :         throw ( beans::UnknownPropertyException,
    3005             :                 beans::PropertyVetoException,
    3006             :                 lang::IllegalArgumentException,
    3007             :                 lang::WrappedTargetException,
    3008             :                 uno::RuntimeException, std::exception )
    3009             : {
    3010       35722 :     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    3011             : 
    3012       35722 :     if ( !m_pImpl )
    3013             :     {
    3014             :         SAL_INFO("package.xstor", "Disposed!");
    3015           0 :         throw lang::DisposedException();
    3016             :     }
    3017             : 
    3018       35722 :     m_pImpl->GetStreamProperties();
    3019       71444 :     OUString aCompressedString( "Compressed" );
    3020       71444 :     OUString aMediaTypeString( "MediaType" );
    3021       35722 :     if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE && aPropertyName.equals( aMediaTypeString ) )
    3022             :     {
    3023             :         // if the "Compressed" property is not set explicitly, the MediaType can change the default value
    3024        7646 :         bool bCompressedValueFromType = true;
    3025        7646 :         OUString aType;
    3026        7646 :         aValue >>= aType;
    3027             : 
    3028        7646 :         if ( !m_pImpl->m_bCompressedSetExplicit )
    3029             :         {
    3030        5742 :             if ( aType == "image/jpeg" || aType == "image/png" || aType == "image/gif" )
    3031          84 :                 bCompressedValueFromType = false;
    3032             :         }
    3033             : 
    3034       38230 :         for ( sal_Int32 nInd = 0; nInd < m_pImpl->m_aProps.getLength(); nInd++ )
    3035             :         {
    3036       30584 :             if ( aPropertyName.equals( m_pImpl->m_aProps[nInd].Name ) )
    3037        7646 :                 m_pImpl->m_aProps[nInd].Value = aValue;
    3038       22938 :             else if ( !m_pImpl->m_bCompressedSetExplicit && aCompressedString.equals( m_pImpl->m_aProps[nInd].Name ) )
    3039        5742 :                 m_pImpl->m_aProps[nInd].Value <<= bCompressedValueFromType;
    3040        7646 :         }
    3041             :     }
    3042       28076 :     else if ( aPropertyName.equals( aCompressedString ) )
    3043             :     {
    3044             :         // if the "Compressed" property is not set explicitly, the MediaType can change the default value
    3045        4636 :         m_pImpl->m_bCompressedSetExplicit = true;
    3046       23180 :         for ( sal_Int32 nInd = 0; nInd < m_pImpl->m_aProps.getLength(); nInd++ )
    3047             :         {
    3048       18544 :             if ( aPropertyName.equals( m_pImpl->m_aProps[nInd].Name ) )
    3049        4636 :                 m_pImpl->m_aProps[nInd].Value = aValue;
    3050             :         }
    3051             :     }
    3052       46880 :     else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
    3053       23440 :             && aPropertyName == "UseCommonStoragePasswordEncryption" )
    3054             :     {
    3055        6960 :         bool bUseCommonEncryption = false;
    3056        6960 :         if ( aValue >>= bUseCommonEncryption )
    3057             :         {
    3058        6960 :             if ( m_bInitOnDemand && m_pImpl->m_bHasInsertedStreamOptimization )
    3059             :             {
    3060             :                 // the data stream is provided to the packagestream directly
    3061           0 :                 m_pImpl->m_bUseCommonEncryption = bUseCommonEncryption;
    3062             :             }
    3063        6960 :             else if ( bUseCommonEncryption )
    3064             :             {
    3065        6954 :                 if ( !m_pImpl->m_bUseCommonEncryption )
    3066             :                 {
    3067           0 :                     m_pImpl->SetDecrypted();
    3068           0 :                     m_pImpl->m_bUseCommonEncryption = true;
    3069             :                 }
    3070             :             }
    3071             :             else
    3072           6 :                 m_pImpl->m_bUseCommonEncryption = false;
    3073             :         }
    3074             :         else
    3075           0 :             throw lang::IllegalArgumentException(); //TODO
    3076             :     }
    3077       16480 :     else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aPropertyName.equals( aMediaTypeString ) )
    3078             :     {
    3079       65040 :         for ( sal_Int32 nInd = 0; nInd < m_pImpl->m_aProps.getLength(); nInd++ )
    3080             :         {
    3081       48780 :             if ( aPropertyName.equals( m_pImpl->m_aProps[nInd].Name ) )
    3082       16260 :                 m_pImpl->m_aProps[nInd].Value = aValue;
    3083             :         }
    3084             :     }
    3085         220 :     else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aPropertyName == "RelationsInfoStream" )
    3086             :     {
    3087           0 :         uno::Reference< io::XInputStream > xInRelStream;
    3088           0 :         if ( ( aValue >>= xInRelStream ) && xInRelStream.is() )
    3089             :         {
    3090           0 :             uno::Reference< io::XSeekable > xSeek( xInRelStream, uno::UNO_QUERY );
    3091           0 :             if ( !xSeek.is() )
    3092             :             {
    3093             :                 // currently this is an internal property that is used for optimization
    3094             :                 // and the stream must support XSeekable interface
    3095             :                 // TODO/LATER: in future it can be changed if property is used from outside
    3096           0 :                 throw lang::IllegalArgumentException(); // TODO
    3097             :             }
    3098             : 
    3099           0 :             m_pImpl->m_xNewRelInfoStream = xInRelStream;
    3100           0 :             m_pImpl->m_aNewRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
    3101           0 :             m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED_STREAM;
    3102             :         }
    3103             :         else
    3104           0 :             throw lang::IllegalArgumentException(); // TODO
    3105             :     }
    3106         220 :     else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aPropertyName == "RelationsInfo" )
    3107             :     {
    3108           0 :         if ( aValue >>= m_pImpl->m_aNewRelInfo )
    3109             :         {
    3110             :         }
    3111             :         else
    3112           0 :             throw lang::IllegalArgumentException(); // TODO
    3113             :     }
    3114         220 :     else if ( aPropertyName == "Size" )
    3115           0 :         throw beans::PropertyVetoException(); // TODO
    3116         440 :     else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
    3117         220 :            && ( aPropertyName == "IsEncrypted" || aPropertyName == "Encrypted" ) )
    3118           0 :         throw beans::PropertyVetoException(); // TODO
    3119         220 :     else if ( aPropertyName == "RelId" )
    3120             :     {
    3121         220 :         aValue >>= m_pImpl->m_nRelId;
    3122             :     }
    3123             :     else
    3124           0 :         throw beans::UnknownPropertyException(); // TODO
    3125             : 
    3126       35722 :     m_pImpl->m_bHasDataToFlush = true;
    3127       71444 :     ModifyParentUnlockMutex_Impl( aGuard );
    3128       35722 : }
    3129             : 
    3130        8264 : uno::Any SAL_CALL OWriteStream::getPropertyValue( const OUString& aProp )
    3131             :         throw ( beans::UnknownPropertyException,
    3132             :                 lang::WrappedTargetException,
    3133             :                 uno::RuntimeException, std::exception )
    3134             : {
    3135        8264 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    3136             : 
    3137        8264 :     if ( !m_pImpl )
    3138             :     {
    3139             :         SAL_INFO("package.xstor", "Disposed!");
    3140           0 :         throw lang::DisposedException();
    3141             :     }
    3142             : 
    3143        8264 :     if ( aProp == "RelId" )
    3144             :     {
    3145        8264 :         return uno::makeAny( m_pImpl->GetNewRelId() );
    3146             :     }
    3147             : 
    3148           0 :     OUString aPropertyName;
    3149           0 :     if ( aProp == "IsEncrypted" )
    3150           0 :         aPropertyName = "Encrypted";
    3151             :     else
    3152           0 :         aPropertyName = aProp;
    3153             : 
    3154           0 :     if ( ( ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE || m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
    3155           0 :             && aPropertyName == "MediaType" )
    3156           0 :       || ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE && aPropertyName == "Encrypted" )
    3157           0 :       || aPropertyName == "Compressed" )
    3158             :     {
    3159           0 :         m_pImpl->GetStreamProperties();
    3160             : 
    3161           0 :         for ( sal_Int32 nInd = 0; nInd < m_pImpl->m_aProps.getLength(); nInd++ )
    3162             :         {
    3163           0 :             if ( aPropertyName.equals( m_pImpl->m_aProps[nInd].Name ) )
    3164           0 :                 return m_pImpl->m_aProps[nInd].Value;
    3165             :         }
    3166             :     }
    3167           0 :     else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
    3168           0 :             && aPropertyName == "UseCommonStoragePasswordEncryption" )
    3169           0 :         return uno::makeAny( m_pImpl->m_bUseCommonEncryption );
    3170           0 :     else if ( aPropertyName == "Size" )
    3171             :     {
    3172           0 :         bool bThrow = false;
    3173             :         try
    3174             :         {
    3175           0 :             CheckInitOnDemand();
    3176             :         }
    3177           0 :         catch (const io::IOException&)
    3178             :         {
    3179           0 :             bThrow = true;
    3180             :         }
    3181           0 :         if (bThrow || !m_xSeekable.is())
    3182           0 :             throw uno::RuntimeException();
    3183             : 
    3184           0 :         return uno::makeAny( m_xSeekable->getLength() );
    3185             :     }
    3186             : 
    3187        8264 :     throw beans::UnknownPropertyException(); // TODO
    3188             : }
    3189             : 
    3190           0 : void SAL_CALL OWriteStream::addPropertyChangeListener(
    3191             :     const OUString& /*aPropertyName*/,
    3192             :     const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
    3193             :         throw ( beans::UnknownPropertyException,
    3194             :                 lang::WrappedTargetException,
    3195             :                 uno::RuntimeException, std::exception )
    3196             : {
    3197           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    3198             : 
    3199           0 :     if ( !m_pImpl )
    3200             :     {
    3201             :         SAL_INFO("package.xstor", "Disposed!");
    3202           0 :         throw lang::DisposedException();
    3203           0 :     }
    3204             : 
    3205             :     //TODO:
    3206           0 : }
    3207             : 
    3208           0 : void SAL_CALL OWriteStream::removePropertyChangeListener(
    3209             :     const OUString& /*aPropertyName*/,
    3210             :     const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
    3211             :         throw ( beans::UnknownPropertyException,
    3212             :                 lang::WrappedTargetException,
    3213             :                 uno::RuntimeException, std::exception )
    3214             : {
    3215           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    3216             : 
    3217           0 :     if ( !m_pImpl )
    3218             :     {
    3219             :         SAL_INFO("package.xstor", "Disposed!");
    3220           0 :         throw lang::DisposedException();
    3221           0 :     }
    3222             : 
    3223             :     //TODO:
    3224           0 : }
    3225             : 
    3226           0 : void SAL_CALL OWriteStream::addVetoableChangeListener(
    3227             :     const OUString& /*PropertyName*/,
    3228             :     const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
    3229             :         throw ( beans::UnknownPropertyException,
    3230             :                 lang::WrappedTargetException,
    3231             :                 uno::RuntimeException, std::exception )
    3232             : {
    3233           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    3234             : 
    3235           0 :     if ( !m_pImpl )
    3236             :     {
    3237             :         SAL_INFO("package.xstor", "Disposed!");
    3238           0 :         throw lang::DisposedException();
    3239           0 :     }
    3240             : 
    3241             :     //TODO:
    3242           0 : }
    3243             : 
    3244           0 : void SAL_CALL OWriteStream::removeVetoableChangeListener(
    3245             :     const OUString& /*PropertyName*/,
    3246             :     const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
    3247             :         throw ( beans::UnknownPropertyException,
    3248             :                 lang::WrappedTargetException,
    3249             :                 uno::RuntimeException, std::exception )
    3250             : {
    3251           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    3252             : 
    3253           0 :     if ( !m_pImpl )
    3254             :     {
    3255             :         SAL_INFO("package.xstor", "Disposed!");
    3256           0 :         throw lang::DisposedException();
    3257           0 :     }
    3258             : 
    3259             :     //TODO:
    3260           0 : }
    3261             : 
    3262             : //  XTransactedObject
    3263             : 
    3264           0 : void OWriteStream::BroadcastTransaction( sal_Int8 nMessage )
    3265             : /*
    3266             :     1 - preCommit
    3267             :     2 - commited
    3268             :     3 - preRevert
    3269             :     4 - reverted
    3270             : */
    3271             : {
    3272             :     // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
    3273           0 :     if ( !m_pImpl )
    3274             :     {
    3275             :         SAL_INFO("package.xstor", "Disposed!");
    3276           0 :         throw lang::DisposedException();
    3277             :     }
    3278             : 
    3279           0 :        lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
    3280             : 
    3281             :        ::cppu::OInterfaceContainerHelper* pContainer =
    3282             :             m_pData->m_aListenersContainer.getContainer(
    3283           0 :                 cppu::UnoType<embed::XTransactionListener>::get());
    3284           0 :        if ( pContainer )
    3285             :     {
    3286           0 :            ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
    3287           0 :            while ( pIterator.hasMoreElements( ) )
    3288             :            {
    3289             :             OSL_ENSURE( nMessage >= 1 && nMessage <= 4, "Wrong internal notification code is used!\n" );
    3290             : 
    3291           0 :             switch( nMessage )
    3292             :             {
    3293             :                 case STOR_MESS_PRECOMMIT:
    3294           0 :                        static_cast<embed::XTransactionListener*>( pIterator.next( ) )->preCommit( aSource );
    3295           0 :                     break;
    3296             :                 case STOR_MESS_COMMITED:
    3297           0 :                        static_cast<embed::XTransactionListener*>( pIterator.next( ) )->commited( aSource );
    3298           0 :                     break;
    3299             :                 case STOR_MESS_PREREVERT:
    3300           0 :                        static_cast<embed::XTransactionListener*>( pIterator.next( ) )->preRevert( aSource );
    3301           0 :                     break;
    3302             :                 case STOR_MESS_REVERTED:
    3303           0 :                        static_cast< embed::XTransactionListener*>( pIterator.next( ) )->reverted( aSource );
    3304           0 :                     break;
    3305             :             }
    3306           0 :            }
    3307           0 :     }
    3308           0 : }
    3309           0 : void SAL_CALL OWriteStream::commit()
    3310             :         throw ( io::IOException,
    3311             :                 embed::StorageWrappedTargetException,
    3312             :                 uno::RuntimeException, std::exception )
    3313             : {
    3314             :     SAL_INFO( "package.xstor", "package (mv76033) OWriteStream::commit" );
    3315             : 
    3316           0 :     if ( !m_pImpl )
    3317             :     {
    3318             :         SAL_INFO("package.xstor", "Disposed!");
    3319           0 :         throw lang::DisposedException();
    3320             :     }
    3321             : 
    3322           0 :     if ( !m_bTransacted )
    3323           0 :         throw uno::RuntimeException();
    3324             : 
    3325             :     try {
    3326           0 :         BroadcastTransaction( STOR_MESS_PRECOMMIT );
    3327             : 
    3328           0 :         ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    3329             : 
    3330           0 :         if ( !m_pImpl )
    3331             :         {
    3332             :             SAL_INFO("package.xstor", "Disposed!");
    3333           0 :             throw lang::DisposedException();
    3334             :         }
    3335             : 
    3336           0 :         m_pImpl->Commit();
    3337             : 
    3338             :         // when the storage is commited the parent is modified
    3339           0 :         ModifyParentUnlockMutex_Impl( aGuard );
    3340             :     }
    3341           0 :     catch( const io::IOException& rIOException )
    3342             :     {
    3343           0 :         m_pImpl->AddLog( rIOException.Message );
    3344           0 :         m_pImpl->AddLog( "Rethrow" );
    3345           0 :         throw;
    3346             :     }
    3347           0 :     catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
    3348             :     {
    3349           0 :         m_pImpl->AddLog( rStorageWrappedTargetException.Message );
    3350           0 :         m_pImpl->AddLog( "Rethrow" );
    3351           0 :         throw;
    3352             :     }
    3353           0 :     catch( const uno::RuntimeException& rRuntimeException )
    3354             :     {
    3355           0 :         m_pImpl->AddLog( rRuntimeException.Message );
    3356           0 :         m_pImpl->AddLog( "Rethrow" );
    3357           0 :         throw;
    3358             :     }
    3359           0 :     catch( const uno::Exception& rException )
    3360             :     {
    3361           0 :         m_pImpl->AddLog( rException.Message );
    3362           0 :         m_pImpl->AddLog( "Rethrow" );
    3363             : 
    3364           0 :         uno::Any aCaught( ::cppu::getCaughtException() );
    3365             :         throw embed::StorageWrappedTargetException( "Problems on commit!",
    3366             :                                   static_cast< ::cppu::OWeakObject* >( this ),
    3367           0 :                                   aCaught );
    3368             :     }
    3369             : 
    3370           0 :     BroadcastTransaction( STOR_MESS_COMMITED );
    3371           0 : }
    3372             : 
    3373           0 : void SAL_CALL OWriteStream::revert()
    3374             :         throw ( io::IOException,
    3375             :                 embed::StorageWrappedTargetException,
    3376             :                 uno::RuntimeException, std::exception )
    3377             : {
    3378             :     SAL_INFO( "package.xstor", "package (mv76033) OWriteStream::revert" );
    3379             : 
    3380             :     // the method removes all the changes done after last commit
    3381             : 
    3382           0 :     if ( !m_pImpl )
    3383             :     {
    3384             :         SAL_INFO("package.xstor", "Disposed!");
    3385           0 :         throw lang::DisposedException();
    3386             :     }
    3387             : 
    3388           0 :     if ( !m_bTransacted )
    3389           0 :         throw uno::RuntimeException();
    3390             : 
    3391           0 :     BroadcastTransaction( STOR_MESS_PREREVERT );
    3392             : 
    3393           0 :     ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    3394             : 
    3395           0 :     if ( !m_pImpl )
    3396             :     {
    3397             :         SAL_INFO("package.xstor", "Disposed!");
    3398           0 :         throw lang::DisposedException();
    3399             :     }
    3400             : 
    3401             :     try {
    3402           0 :         m_pImpl->Revert();
    3403             :     }
    3404           0 :     catch( const io::IOException& rIOException )
    3405             :     {
    3406           0 :         m_pImpl->AddLog( rIOException.Message );
    3407           0 :         m_pImpl->AddLog( "Rethrow" );
    3408           0 :         throw;
    3409             :     }
    3410           0 :     catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
    3411             :     {
    3412           0 :         m_pImpl->AddLog( rStorageWrappedTargetException.Message );
    3413           0 :         m_pImpl->AddLog( "Rethrow" );
    3414           0 :         throw;
    3415             :     }
    3416           0 :     catch( const uno::RuntimeException& rRuntimeException )
    3417             :     {
    3418           0 :         m_pImpl->AddLog( rRuntimeException.Message );
    3419           0 :         m_pImpl->AddLog( "Rethrow" );
    3420           0 :         throw;
    3421             :     }
    3422           0 :     catch( const uno::Exception& rException )
    3423             :     {
    3424           0 :         m_pImpl->AddLog( rException.Message );
    3425           0 :         m_pImpl->AddLog( "Rethrow" );
    3426             : 
    3427           0 :         uno::Any aCaught( ::cppu::getCaughtException() );
    3428             :         throw embed::StorageWrappedTargetException( "Problems on revert!",
    3429             :                                   static_cast< ::cppu::OWeakObject* >( this ),
    3430           0 :                                   aCaught );
    3431             :     }
    3432             : 
    3433           0 :     aGuard.clear();
    3434             : 
    3435           0 :     BroadcastTransaction( STOR_MESS_REVERTED );
    3436           0 : }
    3437             : 
    3438             : //  XTransactionBroadcaster
    3439             : 
    3440           0 : void SAL_CALL OWriteStream::addTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
    3441             :         throw ( uno::RuntimeException, std::exception )
    3442             : {
    3443           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    3444             : 
    3445           0 :     if ( !m_pImpl )
    3446             :     {
    3447             :         SAL_INFO("package.xstor", "Disposed!");
    3448           0 :         throw lang::DisposedException();
    3449             :     }
    3450             : 
    3451           0 :     if ( !m_bTransacted )
    3452           0 :         throw uno::RuntimeException();
    3453             : 
    3454           0 :     m_pData->m_aListenersContainer.addInterface( cppu::UnoType<embed::XTransactionListener>::get(),
    3455           0 :                                                 aListener );
    3456           0 : }
    3457             : 
    3458           0 : void SAL_CALL OWriteStream::removeTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
    3459             :         throw ( uno::RuntimeException, std::exception )
    3460             : {
    3461           0 :     ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
    3462             : 
    3463           0 :     if ( !m_pImpl )
    3464             :     {
    3465             :         SAL_INFO("package.xstor", "Disposed!");
    3466           0 :         throw lang::DisposedException();
    3467             :     }
    3468             : 
    3469           0 :     if ( !m_bTransacted )
    3470           0 :         throw uno::RuntimeException();
    3471             : 
    3472           0 :     m_pData->m_aListenersContainer.removeInterface( cppu::UnoType<embed::XTransactionListener>::get(),
    3473           0 :                                                     aListener );
    3474           0 : }
    3475             : 
    3476             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10