LCOV - code coverage report
Current view: top level - package/source/xstor - owriteablestream.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 758 1619 46.8 %
Date: 2014-04-11 Functions: 61 101 60.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10