LCOV - code coverage report
Current view: top level - package/source/xstor - owriteablestream.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 802 1584 50.6 %
Date: 2015-06-13 12:38:46 Functions: 67 102 65.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11