1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: owriteablestream.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_package.hxx"
33 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
34 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
35 #include <com/sun/star/lang/DisposedException.hpp>
36 #include <com/sun/star/lang/XUnoTunnel.hpp>
37 #include <com/sun/star/lang/XTypeProvider.hpp>
38 #include <com/sun/star/io/XInputStream.hpp>
39 #include <com/sun/star/io/IOException.hpp>
40 #include <com/sun/star/embed/ElementModes.hpp>
41 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
42 #include <cppuhelper/typeprovider.hxx>
43 #include <cppuhelper/exc_hlp.hxx>
44 #include <osl/diagnose.h>
46 #include <comphelper/processfactory.hxx>
47 #include <comphelper/componentcontext.hxx>
48 #include <comphelper/storagehelper.hxx>
49 #include <comphelper/ofopxmlhelper.hxx>
51 #include "owriteablestream.hxx"
52 #include "oseekinstream.hxx"
53 #include "mutexholder.hxx"
54 #include "xstorage.hxx"
56 #include <rtl/digest.h>
57 #include <rtl/logfile.hxx>
59 // since the copying uses 32000 blocks usually, it makes sense to have a smaller size
60 #define MAX_STORCACHE_SIZE 30000
63 using namespace ::com::sun::star
;
67 //-----------------------------------------------
68 uno::Sequence
< sal_Int8
> MakeKeyFromPass( const ::rtl::OUString
& aPass
, sal_Bool bUseUTF
)
70 // MS_1252 encoding was used for SO60 document format password encoding,
71 // this encoding supports only a minor subset of nonascii characters,
72 // but for compatibility reasons it has to be used for old document formats
74 ::rtl::OString aByteStrPass
;
76 aByteStrPass
= ::rtl::OUStringToOString( aPass
, RTL_TEXTENCODING_UTF8
);
78 aByteStrPass
= ::rtl::OUStringToOString( aPass
, RTL_TEXTENCODING_MS_1252
);
80 sal_uInt8 pBuffer
[RTL_DIGEST_LENGTH_SHA1
];
81 rtlDigestError nError
= rtl_digest_SHA1( aByteStrPass
.getStr(),
82 aByteStrPass
.getLength(),
84 RTL_DIGEST_LENGTH_SHA1
);
86 if ( nError
!= rtl_Digest_E_None
)
87 throw uno::RuntimeException();
89 return uno::Sequence
< sal_Int8
>( (sal_Int8
*)pBuffer
, RTL_DIGEST_LENGTH_SHA1
);
93 //-----------------------------------------------
94 void StaticAddLog( const ::rtl::OUString
& aMessage
)
98 ::comphelper::ComponentContext
aContext( ::comphelper::getProcessServiceFactory() );
101 uno::Reference
< logging::XSimpleLogRing
> xLogRing( aContext
.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), uno::UNO_QUERY_THROW
);
102 xLogRing
->logString( aMessage
);
105 catch( uno::Exception
& )
110 } // namespace package
112 // ================================================================
115 //-----------------------------------------------
116 void SetEncryptionKeyProperty_Impl( const uno::Reference
< beans::XPropertySet
>& xPropertySet
,
117 const uno::Sequence
< sal_Int8
>& aKey
)
119 OSL_ENSURE( xPropertySet
.is(), "No property set is provided!\n" );
120 if ( !xPropertySet
.is() )
121 throw uno::RuntimeException();
123 ::rtl::OUString aString_EncryptionKey
= ::rtl::OUString::createFromAscii( "EncryptionKey" );
125 xPropertySet
->setPropertyValue( aString_EncryptionKey
, uno::makeAny( aKey
) );
127 catch ( uno::Exception
& aException
)
129 ::package::StaticAddLog( aException
.Message
);
130 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Can't set encryption" ) ) );
131 OSL_ENSURE( sal_False
, "Can't write encryption related properties!\n" );
132 throw io::IOException(); // TODO
136 //-----------------------------------------------
137 uno::Any
GetEncryptionKeyProperty_Impl( const uno::Reference
< beans::XPropertySet
>& xPropertySet
)
139 OSL_ENSURE( xPropertySet
.is(), "No property set is provided!\n" );
140 if ( !xPropertySet
.is() )
141 throw uno::RuntimeException();
143 ::rtl::OUString aString_EncryptionKey
= ::rtl::OUString::createFromAscii( "EncryptionKey" );
145 return xPropertySet
->getPropertyValue( aString_EncryptionKey
);
147 catch ( uno::Exception
& aException
)
149 ::package::StaticAddLog( aException
.Message
);
150 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Can't get encryption property" ) ) );
152 OSL_ENSURE( sal_False
, "Can't get encryption related properties!\n" );
153 throw io::IOException(); // TODO
157 //-----------------------------------------------
158 sal_Bool
SequencesEqual( uno::Sequence
< sal_Int8
> aSequence1
, uno::Sequence
< sal_Int8
> aSequence2
)
160 if ( aSequence1
.getLength() != aSequence2
.getLength() )
163 for ( sal_Int32 nInd
= 0; nInd
< aSequence1
.getLength(); nInd
++ )
164 if ( aSequence1
[nInd
] != aSequence2
[nInd
] )
170 //-----------------------------------------------
171 sal_Bool
KillFile( const ::rtl::OUString
& aURL
, const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
173 if ( !xFactory
.is() )
176 sal_Bool bRet
= sal_False
;
180 uno::Reference
< ucb::XSimpleFileAccess
> xAccess(
181 xFactory
->createInstance (
182 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
187 xAccess
->kill( aURL
);
191 catch( uno::Exception
& aException
)
193 ::package::StaticAddLog( aException
.Message
);
194 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Quiet exception" ) ) );
200 const sal_Int32 n_ConstBufferSize
= 32000;
202 //-----------------------------------------------
203 ::rtl::OUString
GetNewTempFileURL( const uno::Reference
< lang::XMultiServiceFactory
> xFactory
)
205 ::rtl::OUString aTempURL
;
207 uno::Reference
< beans::XPropertySet
> xTempFile(
208 xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
211 if ( !xTempFile
.is() )
212 throw uno::RuntimeException(); // TODO
215 xTempFile
->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ), uno::makeAny( sal_False
) );
216 uno::Any aUrl
= xTempFile
->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
219 catch ( uno::Exception
& aException
)
221 ::package::StaticAddLog( aException
.Message
);
222 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Quiet exception" ) ) );
225 if ( !aTempURL
.getLength() )
226 throw uno::RuntimeException(); // TODO: can not create tempfile
231 //-----------------------------------------------
232 uno::Reference
< io::XStream
> CreateMemoryStream( const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
234 if ( !xFactory
.is() )
235 throw uno::RuntimeException();
237 return uno::Reference
< io::XStream
>( xFactory
->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.comp.MemoryStream" ) ), uno::UNO_QUERY_THROW
);
240 } // anonymous namespace
241 // ================================================================
243 //-----------------------------------------------
244 OWriteStream_Impl::OWriteStream_Impl( OStorage_Impl
* pParent
,
245 const uno::Reference
< packages::XDataSinkEncrSupport
>& xPackageStream
,
246 const uno::Reference
< lang::XSingleServiceFactory
>& xPackage
,
247 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
,
248 sal_Bool bForceEncrypted
,
249 sal_Int16 nStorageType
,
250 sal_Bool bDefaultCompress
,
251 const uno::Reference
< io::XInputStream
>& xRelInfoStream
)
252 : m_pAntiImpl( NULL
)
253 , m_bHasDataToFlush( sal_False
)
254 , m_bFlushed( sal_False
)
255 , m_xPackageStream( xPackageStream
)
256 , m_xFactory( xFactory
)
257 , m_pParent( pParent
)
258 , m_bForceEncrypted( bForceEncrypted
)
259 , m_bUseCommonPass( !bForceEncrypted
&& nStorageType
== PACKAGE_STORAGE
)
260 , m_bHasCachedPassword( sal_False
)
261 , m_bCompressedSetExplicit( !bDefaultCompress
)
262 , m_xPackage( xPackage
)
263 , m_bHasInsertedStreamOptimization( sal_False
)
264 , m_nStorageType( nStorageType
)
265 , m_xOrigRelInfoStream( xRelInfoStream
)
266 , m_bOrigRelInfoBroken( sal_False
)
267 , m_nRelInfoStatus( RELINFO_NO_INIT
)
270 OSL_ENSURE( xPackageStream
.is(), "No package stream is provided!\n" );
271 OSL_ENSURE( xPackage
.is(), "No package component is provided!\n" );
272 OSL_ENSURE( m_xFactory
.is(), "No package stream is provided!\n" );
273 OSL_ENSURE( pParent
, "No parent storage is provided!\n" );
274 OSL_ENSURE( m_nStorageType
== OFOPXML_STORAGE
|| !m_xOrigRelInfoStream
.is(), "The Relations info makes sence only for OFOPXML format!\n" );
277 //-----------------------------------------------
278 OWriteStream_Impl::~OWriteStream_Impl()
282 if ( m_aTempURL
.getLength() )
284 KillFile( m_aTempURL
, GetServiceFactory() );
285 m_aTempURL
= ::rtl::OUString();
291 //-----------------------------------------------
292 void OWriteStream_Impl::CleanCacheStream()
294 if ( m_xCacheStream
.is() )
298 uno::Reference
< io::XInputStream
> xInputCache
= m_xCacheStream
->getInputStream();
299 if ( xInputCache
.is() )
300 xInputCache
->closeInput();
302 catch( uno::Exception
& )
307 uno::Reference
< io::XOutputStream
> xOutputCache
= m_xCacheStream
->getOutputStream();
308 if ( xOutputCache
.is() )
309 xOutputCache
->closeOutput();
311 catch( uno::Exception
& )
314 m_xCacheStream
= uno::Reference
< io::XStream
>();
315 m_xCacheSeek
= uno::Reference
< io::XSeekable
>();
319 //-----------------------------------------------
320 void OWriteStream_Impl::AddLog( const ::rtl::OUString
& aMessage
)
322 if ( !m_xLogRing
.is() )
326 ::comphelper::ComponentContext
aContext( ::comphelper::getProcessServiceFactory() );
328 m_xLogRing
.set( aContext
.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), uno::UNO_QUERY_THROW
);
330 catch( uno::Exception
& )
336 if ( m_xLogRing
.is() )
337 m_xLogRing
->logString( aMessage
);
341 //-----------------------------------------------
342 void OWriteStream_Impl::InsertIntoPackageFolder( const ::rtl::OUString
& aName
,
343 const uno::Reference
< container::XNameContainer
>& xParentPackageFolder
)
345 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() );
347 OSL_ENSURE( m_bFlushed
, "This method must not be called for nonflushed streams!\n" );
350 OSL_ENSURE( m_xPackageStream
.is(), "An inserted stream is incomplete!\n" );
351 uno::Reference
< lang::XUnoTunnel
> xTunnel( m_xPackageStream
, uno::UNO_QUERY
);
353 throw uno::RuntimeException(); // TODO
355 xParentPackageFolder
->insertByName( aName
, uno::makeAny( xTunnel
) );
357 m_bFlushed
= sal_False
;
358 m_bHasInsertedStreamOptimization
= sal_False
;
361 //-----------------------------------------------
362 sal_Bool
OWriteStream_Impl::IsEncrypted()
364 if ( m_nStorageType
!= PACKAGE_STORAGE
)
367 if ( m_bForceEncrypted
|| m_bHasCachedPassword
)
370 if ( m_aTempURL
.getLength() || m_xCacheStream
.is() )
373 GetStreamProperties();
375 // the following value can not be cached since it can change after root commit
376 sal_Bool bWasEncr
= sal_False
;
377 uno::Reference
< beans::XPropertySet
> xPropSet( m_xPackageStream
, uno::UNO_QUERY
);
380 uno::Any aValue
= xPropSet
->getPropertyValue( ::rtl::OUString::createFromAscii( "WasEncrypted" ) );
381 if ( !( aValue
>>= bWasEncr
) )
383 OSL_ENSURE( sal_False
, "The property WasEncrypted has wrong type!\n" );
387 sal_Bool bToBeEncr
= sal_False
;
388 for ( sal_Int32 nInd
= 0; nInd
< m_aProps
.getLength(); nInd
++ )
390 if ( m_aProps
[nInd
].Name
.equalsAscii( "Encrypted" ) )
392 if ( !( m_aProps
[nInd
].Value
>>= bToBeEncr
) )
394 OSL_ENSURE( sal_False
, "The property has wrong type!\n" );
399 // since a new key set to the package stream it should not be removed except the case when
400 // the stream becomes nonencrypted
401 uno::Sequence
< sal_Int8
> aKey
;
403 GetEncryptionKeyProperty_Impl( xPropSet
) >>= aKey
;
405 // If the properties must be investigated the stream is either
406 // was never changed or was changed, the parent was commited
407 // and the stream was closed.
408 // That means that if it is intended to use common storage key
409 // it is already has no encryption but is marked to be stored
410 // encrypted and the key is empty.
411 if ( !bWasEncr
&& bToBeEncr
&& !aKey
.getLength() )
413 // the stream is intended to use common storage password
414 m_bUseCommonPass
= sal_True
;
421 //-----------------------------------------------
422 void OWriteStream_Impl::SetDecrypted()
424 OSL_ENSURE( m_nStorageType
== PACKAGE_STORAGE
, "The encryption is supported only for package storages!\n" );
425 if ( m_nStorageType
!= PACKAGE_STORAGE
)
426 throw uno::RuntimeException();
428 GetStreamProperties();
430 // let the stream be modified
431 FillTempGetFileName();
432 m_bHasDataToFlush
= sal_True
;
435 m_bForceEncrypted
= sal_False
;
436 m_bHasCachedPassword
= sal_False
;
437 m_aPass
= ::rtl::OUString();
439 for ( sal_Int32 nInd
= 0; nInd
< m_aProps
.getLength(); nInd
++ )
441 if ( m_aProps
[nInd
].Name
.equalsAscii( "Encrypted" ) )
442 m_aProps
[nInd
].Value
<<= sal_False
;
446 //-----------------------------------------------
447 void OWriteStream_Impl::SetEncryptedWithPass( const ::rtl::OUString
& aPass
)
449 OSL_ENSURE( m_nStorageType
== PACKAGE_STORAGE
, "The encryption is supported only for package storages!\n" );
450 if ( m_nStorageType
!= PACKAGE_STORAGE
)
451 throw uno::RuntimeException();
453 GetStreamProperties();
455 // let the stream be modified
456 FillTempGetFileName();
457 m_bHasDataToFlush
= sal_True
;
459 // introduce encryption info
460 for ( sal_Int32 nInd
= 0; nInd
< m_aProps
.getLength(); nInd
++ )
462 if ( m_aProps
[nInd
].Name
.equalsAscii( "Encrypted" ) )
463 m_aProps
[nInd
].Value
<<= sal_True
;
466 m_bUseCommonPass
= sal_False
; // very important to set it to false
468 m_bHasCachedPassword
= sal_True
;
472 //-----------------------------------------------
473 void OWriteStream_Impl::DisposeWrappers()
475 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() );
479 m_pAntiImpl
->dispose();
481 catch ( uno::RuntimeException
& aRuntimeException
)
483 AddLog( aRuntimeException
.Message
);
484 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Quiet exception" ) ) );
491 if ( !m_aInputStreamsList
.empty() )
493 for ( InputStreamsList_Impl::iterator pStreamIter
= m_aInputStreamsList
.begin();
494 pStreamIter
!= m_aInputStreamsList
.end(); pStreamIter
++ )
496 if ( (*pStreamIter
) )
498 (*pStreamIter
)->InternalDispose();
499 (*pStreamIter
) = NULL
;
503 m_aInputStreamsList
.clear();
507 //-----------------------------------------------
508 uno::Reference
< lang::XMultiServiceFactory
> OWriteStream_Impl::GetServiceFactory()
510 if ( m_xFactory
.is() )
513 return ::comphelper::getProcessServiceFactory();
516 //-----------------------------------------------
517 ::rtl::OUString
OWriteStream_Impl::GetFilledTempFileIfNo( const uno::Reference
< io::XInputStream
>& xStream
)
519 if ( !m_aTempURL
.getLength() )
521 ::rtl::OUString aTempURL
= GetNewTempFileURL( GetServiceFactory() );
524 if ( aTempURL
&& xStream
.is() )
526 uno::Reference
< ucb::XSimpleFileAccess
> xTempAccess(
527 GetServiceFactory()->createInstance (
528 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
531 if ( !xTempAccess
.is() )
532 throw uno::RuntimeException(); // TODO:
534 uno::Reference
< io::XOutputStream
> xTempOutStream
= xTempAccess
->openFileWrite( aTempURL
);
535 if ( xTempOutStream
.is() )
537 // the current position of the original stream should be still OK, copy further
538 ::comphelper::OStorageHelper::CopyInputToOutput( xStream
, xTempOutStream
);
539 xTempOutStream
->closeOutput();
540 xTempOutStream
= uno::Reference
< io::XOutputStream
>();
543 throw io::IOException(); // TODO:
546 catch( packages::WrongPasswordException
& aWrongPasswordException
)
548 AddLog( aWrongPasswordException
.Message
);
549 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
551 KillFile( aTempURL
, GetServiceFactory() );
554 catch( uno::Exception
& aException
)
556 AddLog( aException
.Message
);
557 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
559 KillFile( aTempURL
, GetServiceFactory() );
563 if ( aTempURL
.getLength() )
566 m_aTempURL
= aTempURL
;
572 //-----------------------------------------------
573 ::rtl::OUString
OWriteStream_Impl::FillTempGetFileName()
575 // should try to create cache first, if the amount of contents is too big, the temp file should be taken
576 if ( !m_xCacheStream
.is() && !m_aTempURL
.getLength() )
578 uno::Reference
< io::XInputStream
> xOrigStream
= m_xPackageStream
->getDataStream();
579 if ( !xOrigStream
.is() )
581 // in case of new inserted package stream it is possible that input stream still was not set
582 uno::Reference
< io::XStream
> xCacheStream
= CreateMemoryStream( GetServiceFactory() );
583 OSL_ENSURE( xCacheStream
.is(), "If the stream can not be created an exception must be thrown!\n" );
584 m_xCacheSeek
.set( xCacheStream
, uno::UNO_QUERY_THROW
);
585 m_xCacheStream
= xCacheStream
;
590 uno::Sequence
< sal_Int8
> aData( MAX_STORCACHE_SIZE
+ 1 );
591 nRead
= xOrigStream
->readBytes( aData
, MAX_STORCACHE_SIZE
+ 1 );
592 if ( aData
.getLength() > nRead
)
593 aData
.realloc( nRead
);
595 if ( nRead
&& nRead
<= MAX_STORCACHE_SIZE
)
597 uno::Reference
< io::XStream
> xCacheStream
= CreateMemoryStream( GetServiceFactory() );
598 OSL_ENSURE( xCacheStream
.is(), "If the stream can not be created an exception must be thrown!\n" );
600 uno::Reference
< io::XOutputStream
> xOutStream( xCacheStream
->getOutputStream(), uno::UNO_SET_THROW
);
601 xOutStream
->writeBytes( aData
);
602 m_xCacheSeek
.set( xCacheStream
, uno::UNO_QUERY_THROW
);
603 m_xCacheStream
= xCacheStream
;
604 m_xCacheSeek
->seek( 0 );
606 else if ( nRead
&& !m_aTempURL
.getLength() )
608 m_aTempURL
= GetNewTempFileURL( GetServiceFactory() );
611 if ( m_aTempURL
.getLength() )
613 uno::Reference
< ucb::XSimpleFileAccess
> xTempAccess(
614 GetServiceFactory()->createInstance (
615 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
618 if ( !xTempAccess
.is() )
619 throw uno::RuntimeException(); // TODO:
622 uno::Reference
< io::XOutputStream
> xTempOutStream
= xTempAccess
->openFileWrite( m_aTempURL
);
623 if ( xTempOutStream
.is() )
625 // copy stream contents to the file
626 xTempOutStream
->writeBytes( aData
);
628 // the current position of the original stream should be still OK, copy further
629 ::comphelper::OStorageHelper::CopyInputToOutput( xOrigStream
, xTempOutStream
);
630 xTempOutStream
->closeOutput();
631 xTempOutStream
= uno::Reference
< io::XOutputStream
>();
634 throw io::IOException(); // TODO:
637 catch( packages::WrongPasswordException
& )
639 KillFile( m_aTempURL
, GetServiceFactory() );
640 m_aTempURL
= ::rtl::OUString();
644 catch( uno::Exception
& )
646 KillFile( m_aTempURL
, GetServiceFactory() );
647 m_aTempURL
= ::rtl::OUString();
656 //-----------------------------------------------
657 uno::Reference
< io::XStream
> OWriteStream_Impl::GetTempFileAsStream()
659 uno::Reference
< io::XStream
> xTempStream
;
661 if ( !m_xCacheStream
.is() )
663 if ( !m_aTempURL
.getLength() )
664 m_aTempURL
= FillTempGetFileName();
666 if ( m_aTempURL
.getLength() )
668 // the temporary file is not used if the cache is used
669 uno::Reference
< ucb::XSimpleFileAccess
> xTempAccess(
670 GetServiceFactory()->createInstance (
671 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
674 if ( !xTempAccess
.is() )
675 throw uno::RuntimeException(); // TODO:
679 xTempStream
= xTempAccess
->openFileReadWrite( m_aTempURL
);
681 catch( uno::Exception
& aException
)
683 AddLog( aException
.Message
);
684 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Quiet exception" ) ) );
689 if ( m_xCacheStream
.is() )
690 xTempStream
= m_xCacheStream
;
692 // the method must always return a stream
693 // in case the stream can not be open
694 // an exception should be thrown
695 if ( !xTempStream
.is() )
696 throw io::IOException(); //TODO:
701 //-----------------------------------------------
702 uno::Reference
< io::XInputStream
> OWriteStream_Impl::GetTempFileAsInputStream()
704 uno::Reference
< io::XInputStream
> xInputStream
;
706 if ( !m_xCacheStream
.is() )
708 if ( !m_aTempURL
.getLength() )
709 m_aTempURL
= FillTempGetFileName();
711 if ( m_aTempURL
.getLength() )
713 // the temporary file is not used if the cache is used
714 uno::Reference
< ucb::XSimpleFileAccess
> xTempAccess(
715 GetServiceFactory()->createInstance (
716 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
719 if ( !xTempAccess
.is() )
720 throw uno::RuntimeException(); // TODO:
724 xInputStream
= xTempAccess
->openFileRead( m_aTempURL
);
726 catch( uno::Exception
& aException
)
728 AddLog( aException
.Message
);
729 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Quiet exception" ) ) );
734 if ( m_xCacheStream
.is() )
735 xInputStream
= m_xCacheStream
->getInputStream();
737 // the method must always return a stream
738 // in case the stream can not be open
739 // an exception should be thrown
740 if ( !xInputStream
.is() )
741 throw io::IOException(); // TODO:
746 // =================================================================================================
748 //-----------------------------------------------
749 void OWriteStream_Impl::InsertStreamDirectly( const uno::Reference
< io::XInputStream
>& xInStream
,
750 const uno::Sequence
< beans::PropertyValue
>& aProps
)
752 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
754 // this call can be made only during parent storage commit
755 // the parent storage is responsible for the correct handling
756 // of deleted and renamed contents
758 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
760 if ( m_bHasDataToFlush
)
761 throw io::IOException();
763 OSL_ENSURE( !m_aTempURL
.getLength() && !m_xCacheStream
.is(), "The temporary must not exist!\n" );
765 // use new file as current persistent representation
766 // the new file will be removed after it's stream is closed
767 m_xPackageStream
->setDataStream( xInStream
);
769 // copy properties to the package stream
770 uno::Reference
< beans::XPropertySet
> xPropertySet( m_xPackageStream
, uno::UNO_QUERY
);
771 if ( !xPropertySet
.is() )
772 throw uno::RuntimeException();
774 // The storage-package communication has a problem
775 // the storage caches properties, thus if the package changes one of them itself
776 // the storage does not know about it
778 // Depending from MediaType value the package can change the compressed property itself
779 // Thus if Compressed property is provided it must be set as the latest one
780 sal_Bool bCompressedIsSet
= sal_False
;
781 sal_Bool bCompressed
= sal_False
;
782 ::rtl::OUString
aComprPropName( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) );
783 ::rtl::OUString
aMedTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
784 for ( sal_Int32 nInd
= 0; nInd
< aProps
.getLength(); nInd
++ )
786 if ( aProps
[nInd
].Name
.equals( aComprPropName
) )
788 bCompressedIsSet
= sal_True
;
789 aProps
[nInd
].Value
>>= bCompressed
;
791 else if ( ( m_nStorageType
== OFOPXML_STORAGE
|| m_nStorageType
== PACKAGE_STORAGE
)
792 && aProps
[nInd
].Name
.equals( aMedTypePropName
) )
794 xPropertySet
->setPropertyValue( aProps
[nInd
].Name
, aProps
[nInd
].Value
);
796 else if ( m_nStorageType
== PACKAGE_STORAGE
&& aProps
[nInd
].Name
.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
797 aProps
[nInd
].Value
>>= m_bUseCommonPass
;
799 throw lang::IllegalArgumentException();
801 // if there are cached properties update them
802 if ( aProps
[nInd
].Name
.equals( aMedTypePropName
) || aProps
[nInd
].Name
.equals( aComprPropName
) )
803 for ( sal_Int32 nMemInd
= 0; nMemInd
< m_aProps
.getLength(); nMemInd
++ )
805 if ( aProps
[nInd
].Name
.equals( m_aProps
[nMemInd
].Name
) )
806 m_aProps
[nMemInd
].Value
= aProps
[nInd
].Value
;
810 if ( bCompressedIsSet
)
812 xPropertySet
->setPropertyValue( aComprPropName
, uno::makeAny( (sal_Bool
)bCompressed
) );
813 m_bCompressedSetExplicit
= sal_True
;
816 if ( m_bUseCommonPass
)
818 if ( m_nStorageType
!= PACKAGE_STORAGE
)
819 throw uno::RuntimeException();
821 // set to be encrypted but do not use encryption key
822 xPropertySet
->setPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ),
823 uno::makeAny( uno::Sequence
< sal_Int8
>() ) );
824 xPropertySet
->setPropertyValue( ::rtl::OUString::createFromAscii( "Encrypted" ),
825 uno::makeAny( sal_True
) );
828 // the stream should be free soon, after package is stored
829 m_bHasDataToFlush
= sal_False
;
830 m_bFlushed
= sal_True
; // will allow to use transaction on stream level if will need it
831 m_bHasInsertedStreamOptimization
= sal_True
;
834 //-----------------------------------------------
835 void OWriteStream_Impl::Commit()
837 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
839 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
841 if ( !m_bHasDataToFlush
)
844 uno::Reference
< packages::XDataSinkEncrSupport
> xNewPackageStream
;
845 uno::Sequence
< uno::Any
> aSeq( 1 );
846 aSeq
[0] <<= sal_False
;
848 if ( m_xCacheStream
.is() )
850 uno::Reference
< io::XInputStream
> xInStream( m_xCacheStream
->getInputStream(), uno::UNO_SET_THROW
);
852 xNewPackageStream
= uno::Reference
< packages::XDataSinkEncrSupport
>(
853 m_xPackage
->createInstanceWithArguments( aSeq
),
854 uno::UNO_QUERY_THROW
);
856 xNewPackageStream
->setDataStream( xInStream
);
858 m_xCacheStream
= uno::Reference
< io::XStream
>();
859 m_xCacheSeek
= uno::Reference
< io::XSeekable
>();
862 m_pAntiImpl
->DeInit();
864 else if ( m_aTempURL
.getLength() )
866 uno::Reference
< ucb::XSimpleFileAccess
> xTempAccess(
867 GetServiceFactory()->createInstance (
868 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
871 if ( !xTempAccess
.is() )
872 throw uno::RuntimeException(); // TODO:
874 uno::Reference
< io::XInputStream
> xInStream
;
877 xInStream
= xTempAccess
->openFileRead( m_aTempURL
);
879 catch( uno::Exception
& )
883 if ( !xInStream
.is() )
884 throw io::IOException();
886 xNewPackageStream
= uno::Reference
< packages::XDataSinkEncrSupport
>(
887 m_xPackage
->createInstanceWithArguments( aSeq
),
888 uno::UNO_QUERY_THROW
);
890 // TODO/NEW: Let the temporary file be removed after commit
891 xNewPackageStream
->setDataStream( xInStream
);
892 m_aTempURL
= ::rtl::OUString();
895 m_pAntiImpl
->DeInit();
897 else // if ( m_bHasInsertedStreamOptimization )
899 // if the optimization is used the stream can be accessed directly
900 xNewPackageStream
= m_xPackageStream
;
903 // copy properties to the package stream
904 uno::Reference
< beans::XPropertySet
> xPropertySet( xNewPackageStream
, uno::UNO_QUERY
);
905 if ( !xPropertySet
.is() )
906 throw uno::RuntimeException();
908 for ( sal_Int32 nInd
= 0; nInd
< m_aProps
.getLength(); nInd
++ )
910 if ( m_aProps
[nInd
].Name
.equalsAscii( "Size" ) )
912 if ( m_pAntiImpl
&& !m_bHasInsertedStreamOptimization
&& m_pAntiImpl
->m_xSeekable
.is() )
914 m_aProps
[nInd
].Value
<<= ((sal_Int32
)m_pAntiImpl
->m_xSeekable
->getLength());
915 xPropertySet
->setPropertyValue( m_aProps
[nInd
].Name
, m_aProps
[nInd
].Value
);
919 xPropertySet
->setPropertyValue( m_aProps
[nInd
].Name
, m_aProps
[nInd
].Value
);
922 if ( m_bUseCommonPass
)
924 if ( m_nStorageType
!= PACKAGE_STORAGE
)
925 throw uno::RuntimeException();
927 // set to be encrypted but do not use encryption key
928 xPropertySet
->setPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ),
929 uno::makeAny( uno::Sequence
< sal_Int8
>() ) );
930 xPropertySet
->setPropertyValue( ::rtl::OUString::createFromAscii( "Encrypted" ),
931 uno::makeAny( sal_True
) );
933 else if ( m_bHasCachedPassword
)
935 if ( m_nStorageType
!= PACKAGE_STORAGE
)
936 throw uno::RuntimeException();
938 xPropertySet
->setPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ),
939 uno::makeAny( ::package::MakeKeyFromPass( m_aPass
, sal_True
) ) );
942 // the stream should be free soon, after package is stored
943 m_xPackageStream
= xNewPackageStream
;
944 m_bHasDataToFlush
= sal_False
;
945 m_bFlushed
= sal_True
; // will allow to use transaction on stream level if will need it
948 //-----------------------------------------------
949 void OWriteStream_Impl::Revert()
951 // can be called only from parent storage
952 // means complete reload of the stream
954 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
956 if ( !m_bHasDataToFlush
)
957 return; // nothing to do
959 OSL_ENSURE( m_aTempURL
.getLength() || m_xCacheStream
.is(), "The temporary must exist!\n" );
961 if ( m_xCacheStream
.is() )
963 m_xCacheStream
= uno::Reference
< io::XStream
>();
964 m_xCacheSeek
= uno::Reference
< io::XSeekable
>();
967 if ( m_aTempURL
.getLength() )
969 KillFile( m_aTempURL
, GetServiceFactory() );
970 m_aTempURL
= ::rtl::OUString();
973 m_aProps
.realloc( 0 );
975 m_bHasDataToFlush
= sal_False
;
977 m_bUseCommonPass
= sal_True
;
978 m_bHasCachedPassword
= sal_False
;
979 m_aPass
= ::rtl::OUString();
981 if ( m_nStorageType
== OFOPXML_STORAGE
)
983 // currently the relations storage is changed only on commit
984 m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
985 m_aNewRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
986 if ( m_xOrigRelInfoStream
.is() )
988 // the original stream is still here, that means that it was not parsed
989 m_aOrigRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
990 m_nRelInfoStatus
= RELINFO_NO_INIT
;
994 // the original stream was aready parsed
995 if ( !m_bOrigRelInfoBroken
)
996 m_nRelInfoStatus
= RELINFO_READ
;
998 m_nRelInfoStatus
= RELINFO_BROKEN
;
1003 //-----------------------------------------------
1004 uno::Sequence
< beans::PropertyValue
> OWriteStream_Impl::GetStreamProperties()
1006 if ( !m_aProps
.getLength() )
1007 m_aProps
= ReadPackageStreamProperties();
1012 //-----------------------------------------------
1013 uno::Sequence
< beans::PropertyValue
> OWriteStream_Impl::InsertOwnProps(
1014 const uno::Sequence
< beans::PropertyValue
>& aProps
,
1015 sal_Bool bUseCommonPass
)
1017 uno::Sequence
< beans::PropertyValue
> aResult( aProps
);
1018 sal_Int32 nLen
= aResult
.getLength();
1020 if ( m_nStorageType
== PACKAGE_STORAGE
)
1022 for ( sal_Int32 nInd
= 0; nInd
< nLen
; nInd
++ )
1023 if ( aResult
[nInd
].Name
.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
1025 aResult
[nInd
].Value
<<= bUseCommonPass
;
1029 aResult
.realloc( ++nLen
);
1030 aResult
[nLen
- 1].Name
= ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" );
1031 aResult
[nLen
- 1].Value
<<= bUseCommonPass
;
1033 else if ( m_nStorageType
== OFOPXML_STORAGE
)
1035 ReadRelInfoIfNecessary();
1038 if ( m_nRelInfoStatus
== RELINFO_READ
)
1039 aValue
<<= m_aOrigRelInfo
;
1040 else if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM_READ
|| m_nRelInfoStatus
== RELINFO_CHANGED
)
1041 aValue
<<= m_aNewRelInfo
;
1042 else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
1043 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Wrong relinfo stream!" ) ),
1044 uno::Reference
< uno::XInterface
>() );
1046 for ( sal_Int32 nInd
= 0; nInd
< nLen
; nInd
++ )
1047 if ( aResult
[nInd
].Name
.equalsAscii( "RelationsInfo" ) )
1049 aResult
[nInd
].Value
= aValue
;
1053 aResult
.realloc( ++nLen
);
1054 aResult
[nLen
- 1].Name
= ::rtl::OUString::createFromAscii( "RelationsInfo" );
1055 aResult
[nLen
- 1].Value
= aValue
;
1061 //-----------------------------------------------
1062 sal_Bool
OWriteStream_Impl::IsTransacted()
1064 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1065 return ( m_pAntiImpl
&& m_pAntiImpl
->m_bTransacted
);
1068 void OWriteStream_Impl::ReadRelInfoIfNecessary()
1070 if ( m_nStorageType
!= OFOPXML_STORAGE
)
1073 if ( m_nRelInfoStatus
== RELINFO_NO_INIT
)
1077 // Init from original stream
1078 if ( m_xOrigRelInfoStream
.is() )
1079 m_aOrigRelInfo
= ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
1080 m_xOrigRelInfoStream
,
1081 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/*.rels" ) ),
1084 // in case of success the stream must be thrown away, that means that the OrigRelInfo is initialized
1085 // the reason for this is that the original stream might not be seekable ( at the same time the new
1086 // provided stream must be seekable ), so it must be read only once
1087 m_xOrigRelInfoStream
= uno::Reference
< io::XInputStream
>();
1088 m_nRelInfoStatus
= RELINFO_READ
;
1090 catch( uno::Exception
& aException
)
1092 AddLog( aException
.Message
);
1093 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Quiet exception" ) ) );
1095 m_nRelInfoStatus
= RELINFO_BROKEN
;
1096 m_bOrigRelInfoBroken
= sal_True
;
1099 else if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1101 // Init from the new stream
1104 if ( m_xNewRelInfoStream
.is() )
1105 m_aNewRelInfo
= ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
1106 m_xNewRelInfoStream
,
1107 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/*.rels" ) ),
1110 m_nRelInfoStatus
= RELINFO_CHANGED_STREAM_READ
;
1112 catch( uno::Exception
)
1114 m_nRelInfoStatus
= RELINFO_CHANGED_BROKEN
;
1119 //-----------------------------------------------
1120 uno::Sequence
< beans::PropertyValue
> OWriteStream_Impl::ReadPackageStreamProperties()
1122 sal_Int32 nPropNum
= 0;
1123 if ( m_nStorageType
== ZIP_STORAGE
)
1125 else if ( m_nStorageType
== OFOPXML_STORAGE
)
1127 else if ( m_nStorageType
== PACKAGE_STORAGE
)
1129 uno::Sequence
< beans::PropertyValue
> aResult( nPropNum
);
1131 // The "Compressed" property must be set after "MediaType" property,
1132 // since the setting of the last one can change the value of the first one
1134 if ( m_nStorageType
== OFOPXML_STORAGE
|| m_nStorageType
== PACKAGE_STORAGE
)
1136 aResult
[0].Name
= ::rtl::OUString::createFromAscii("MediaType");
1137 aResult
[1].Name
= ::rtl::OUString::createFromAscii("Compressed");
1138 aResult
[2].Name
= ::rtl::OUString::createFromAscii("Size");
1140 if ( m_nStorageType
== PACKAGE_STORAGE
)
1141 aResult
[3].Name
= ::rtl::OUString::createFromAscii("Encrypted");
1145 aResult
[0].Name
= ::rtl::OUString::createFromAscii("Compressed");
1146 aResult
[1].Name
= ::rtl::OUString::createFromAscii("Size");
1150 // TODO: may be also raw stream should be marked
1152 uno::Reference
< beans::XPropertySet
> xPropSet( m_xPackageStream
, uno::UNO_QUERY
);
1153 if ( xPropSet
.is() )
1155 for ( sal_Int32 nInd
= 0; nInd
< aResult
.getLength(); nInd
++ )
1158 aResult
[nInd
].Value
= xPropSet
->getPropertyValue( aResult
[nInd
].Name
);
1160 catch( uno::Exception
& aException
)
1162 AddLog( aException
.Message
);
1163 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Quiet exception" ) ) );
1165 OSL_ENSURE( sal_False
, "A property can't be retrieved!\n" );
1171 OSL_ENSURE( sal_False
, "Can not get properties from a package stream!\n" );
1172 throw uno::RuntimeException();
1178 //-----------------------------------------------
1179 void OWriteStream_Impl::CopyInternallyTo_Impl( const uno::Reference
< io::XStream
>& xDestStream
,
1180 const ::rtl::OUString
& aPass
)
1182 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1184 OSL_ENSURE( !m_bUseCommonPass
, "The stream can not be encrypted!" );
1186 if ( m_nStorageType
!= PACKAGE_STORAGE
)
1187 throw packages::NoEncryptionException();
1191 m_pAntiImpl
->CopyToStreamInternally_Impl( xDestStream
);
1195 uno::Reference
< io::XStream
> xOwnStream
= GetStream( embed::ElementModes::READ
, aPass
, sal_False
);
1196 if ( !xOwnStream
.is() )
1197 throw io::IOException(); // TODO
1199 OStorage_Impl::completeStorageStreamCopy_Impl( xOwnStream
, xDestStream
, m_nStorageType
, GetAllRelationshipsIfAny() );
1202 uno::Reference
< embed::XEncryptionProtectedSource
> xEncr( xDestStream
, uno::UNO_QUERY
);
1204 xEncr
->setEncryptionPassword( aPass
);
1207 //-----------------------------------------------
1208 uno::Sequence
< uno::Sequence
< beans::StringPair
> > OWriteStream_Impl::GetAllRelationshipsIfAny()
1210 if ( m_nStorageType
!= OFOPXML_STORAGE
)
1211 return uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
1213 ReadRelInfoIfNecessary();
1215 if ( m_nRelInfoStatus
== RELINFO_READ
)
1216 return m_aOrigRelInfo
;
1217 else if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM_READ
|| m_nRelInfoStatus
== RELINFO_CHANGED
)
1218 return m_aNewRelInfo
;
1219 else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
1220 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Wrong relinfo stream!" ) ),
1221 uno::Reference
< uno::XInterface
>() );
1224 //-----------------------------------------------
1225 void OWriteStream_Impl::CopyInternallyTo_Impl( const uno::Reference
< io::XStream
>& xDestStream
)
1227 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1231 m_pAntiImpl
->CopyToStreamInternally_Impl( xDestStream
);
1235 uno::Reference
< io::XStream
> xOwnStream
= GetStream( embed::ElementModes::READ
, sal_False
);
1236 if ( !xOwnStream
.is() )
1237 throw io::IOException(); // TODO
1239 OStorage_Impl::completeStorageStreamCopy_Impl( xOwnStream
, xDestStream
, m_nStorageType
, GetAllRelationshipsIfAny() );
1243 //-----------------------------------------------
1244 uno::Reference
< io::XStream
> OWriteStream_Impl::GetStream( sal_Int32 nStreamMode
, const ::rtl::OUString
& aPass
, sal_Bool bHierarchyAccess
)
1246 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1248 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
1251 throw io::IOException(); // TODO:
1253 if ( !IsEncrypted() )
1254 throw packages::NoEncryptionException();
1256 uno::Reference
< io::XStream
> xResultStream
;
1258 uno::Reference
< beans::XPropertySet
> xPropertySet( m_xPackageStream
, uno::UNO_QUERY
);
1259 if ( !xPropertySet
.is() )
1260 throw uno::RuntimeException();
1262 if ( m_bHasCachedPassword
)
1264 if ( !m_aPass
.equals( aPass
) )
1265 throw packages::WrongPasswordException();
1267 // the correct key must be set already
1268 xResultStream
= GetStream_Impl( nStreamMode
, bHierarchyAccess
);
1272 SetEncryptionKeyProperty_Impl( xPropertySet
, ::package::MakeKeyFromPass( aPass
, sal_True
) );
1275 xResultStream
= GetStream_Impl( nStreamMode
, bHierarchyAccess
);
1277 m_bUseCommonPass
= sal_False
; // very important to set it to false
1278 m_bHasCachedPassword
= sal_True
;
1281 catch( packages::WrongPasswordException
& )
1283 // retry with different encoding
1284 SetEncryptionKeyProperty_Impl( xPropertySet
, ::package::MakeKeyFromPass( aPass
, sal_False
) );
1286 // the stream must be cashed to be resaved
1287 xResultStream
= GetStream_Impl( nStreamMode
| embed::ElementModes::SEEKABLE
, bHierarchyAccess
);
1289 m_bUseCommonPass
= sal_False
; // very important to set it to false
1290 m_bHasCachedPassword
= sal_True
;
1293 // the stream must be resaved with new password encryption
1294 if ( nStreamMode
& embed::ElementModes::WRITE
)
1296 FillTempGetFileName();
1297 m_bHasDataToFlush
= sal_True
;
1299 // TODO/LATER: should the notification be done?
1301 m_pParent
->m_bIsModified
= sal_True
;
1304 catch( packages::WrongPasswordException
& aWrongPasswordException
)
1306 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1307 AddLog( aWrongPasswordException
.Message
);
1308 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
1311 catch ( uno::Exception
& aException
)
1313 AddLog( aException
.Message
);
1314 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Quiet exception" ) ) );
1316 OSL_ENSURE( sal_False
, "Can't write encryption related properties!\n" );
1317 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1318 throw io::IOException(); // TODO:
1321 catch( uno::Exception
& aException
)
1323 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1325 AddLog( aException
.Message
);
1326 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
1332 OSL_ENSURE( xResultStream
.is(), "In case stream can not be retrieved an exception must be thrown!\n" );
1334 return xResultStream
;
1337 //-----------------------------------------------
1338 uno::Reference
< io::XStream
> OWriteStream_Impl::GetStream( sal_Int32 nStreamMode
, sal_Bool bHierarchyAccess
)
1340 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1342 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
1345 throw io::IOException(); // TODO:
1347 uno::Reference
< io::XStream
> xResultStream
;
1349 if ( IsEncrypted() )
1351 ::rtl::OUString aGlobalPass
;
1354 aGlobalPass
= GetCommonRootPass();
1356 catch( packages::NoEncryptionException
& aNoEncryptionException
)
1358 AddLog( aNoEncryptionException
.Message
);
1359 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
1361 throw packages::WrongPasswordException();
1364 xResultStream
= GetStream( nStreamMode
, aGlobalPass
, bHierarchyAccess
);
1367 xResultStream
= GetStream_Impl( nStreamMode
, bHierarchyAccess
);
1369 return xResultStream
;
1372 //-----------------------------------------------
1373 uno::Reference
< io::XStream
> OWriteStream_Impl::GetStream_Impl( sal_Int32 nStreamMode
, sal_Bool bHierarchyAccess
)
1375 // private method, no mutex is used
1376 GetStreamProperties();
1378 // TODO/LATER: this info might be read later, on demand in future
1379 ReadRelInfoIfNecessary();
1381 if ( ( nStreamMode
& embed::ElementModes::READWRITE
) == embed::ElementModes::READ
)
1383 uno::Reference
< io::XInputStream
> xInStream
;
1384 if ( m_xCacheStream
.is() || m_aTempURL
.getLength() )
1385 xInStream
= GetTempFileAsInputStream(); //TODO:
1387 xInStream
= m_xPackageStream
->getDataStream();
1389 // The stream does not exist in the storage
1390 if ( !xInStream
.is() )
1391 throw io::IOException();
1393 OInputCompStream
* pStream
= new OInputCompStream( *this, xInStream
, InsertOwnProps( m_aProps
, m_bUseCommonPass
), m_nStorageType
);
1394 uno::Reference
< io::XStream
> xCompStream(
1395 static_cast< ::cppu::OWeakObject
* >( pStream
),
1397 OSL_ENSURE( xCompStream
.is(),
1398 "OInputCompStream MUST provide XStream interfaces!\n" );
1400 m_aInputStreamsList
.push_back( pStream
);
1403 else if ( ( nStreamMode
& embed::ElementModes::READWRITE
) == embed::ElementModes::SEEKABLEREAD
)
1405 if ( !m_xCacheStream
.is() && !m_aTempURL
.getLength() && !( m_xPackageStream
->getDataStream().is() ) )
1407 // The stream does not exist in the storage
1408 throw io::IOException();
1411 uno::Reference
< io::XInputStream
> xInStream
;
1413 xInStream
= GetTempFileAsInputStream(); //TODO:
1415 if ( !xInStream
.is() )
1416 throw io::IOException();
1418 OInputSeekStream
* pStream
= new OInputSeekStream( *this, xInStream
, InsertOwnProps( m_aProps
, m_bUseCommonPass
), m_nStorageType
);
1419 uno::Reference
< io::XStream
> xSeekStream(
1420 static_cast< ::cppu::OWeakObject
* >( pStream
),
1422 OSL_ENSURE( xSeekStream
.is(),
1423 "OInputSeekStream MUST provide XStream interfaces!\n" );
1425 m_aInputStreamsList
.push_back( pStream
);
1428 else if ( ( nStreamMode
& embed::ElementModes::WRITE
) == embed::ElementModes::WRITE
)
1430 if ( !m_aInputStreamsList
.empty() )
1431 throw io::IOException(); // TODO:
1433 uno::Reference
< io::XStream
> xStream
;
1434 if ( ( nStreamMode
& embed::ElementModes::TRUNCATE
) == embed::ElementModes::TRUNCATE
)
1436 if ( m_aTempURL
.getLength() )
1438 KillFile( m_aTempURL
, GetServiceFactory() );
1439 m_aTempURL
= ::rtl::OUString();
1441 if ( m_xCacheStream
.is() )
1444 m_bHasDataToFlush
= sal_True
;
1446 // this call is triggered by the parent and it will recognize the change of the state
1448 m_pParent
->m_bIsModified
= sal_True
;
1450 xStream
= CreateMemoryStream( GetServiceFactory() );
1451 m_xCacheSeek
.set( xStream
, uno::UNO_QUERY_THROW
);
1452 m_xCacheStream
= xStream
;
1454 else if ( !m_bHasInsertedStreamOptimization
)
1456 if ( !m_aTempURL
.getLength() && !m_xCacheStream
.is() && !( m_xPackageStream
->getDataStream().is() ) )
1458 // The stream does not exist in the storage
1459 m_bHasDataToFlush
= sal_True
;
1461 // this call is triggered by the parent and it will recognize the change of the state
1463 m_pParent
->m_bIsModified
= sal_True
;
1464 xStream
= GetTempFileAsStream();
1467 // if the stream exists the temporary file is created on demand
1468 // xStream = GetTempFileAsStream();
1471 if ( !xStream
.is() )
1472 m_pAntiImpl
= new OWriteStream( this, bHierarchyAccess
);
1474 m_pAntiImpl
= new OWriteStream( this, xStream
, bHierarchyAccess
);
1476 uno::Reference
< io::XStream
> xWriteStream
=
1477 uno::Reference
< io::XStream
>( static_cast< ::cppu::OWeakObject
* >( m_pAntiImpl
),
1480 OSL_ENSURE( xWriteStream
.is(), "OWriteStream MUST implement XStream && XComponent interfaces!\n" );
1482 return xWriteStream
;
1485 throw lang::IllegalArgumentException(); // TODO
1488 //-----------------------------------------------
1489 uno::Reference
< io::XInputStream
> OWriteStream_Impl::GetPlainRawInStream()
1491 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1493 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
1495 // this method is used only internally, this stream object should not go outside of this implementation
1496 // if ( m_pAntiImpl )
1497 // throw io::IOException(); // TODO:
1499 return m_xPackageStream
->getPlainRawStream();
1502 //-----------------------------------------------
1503 uno::Reference
< io::XInputStream
> OWriteStream_Impl::GetRawInStream()
1505 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1507 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
1510 throw io::IOException(); // TODO:
1512 OSL_ENSURE( IsEncrypted(), "Impossible to get raw representation for nonencrypted stream!\n" );
1513 if ( !IsEncrypted() )
1514 throw packages::NoEncryptionException();
1516 return m_xPackageStream
->getRawStream();
1519 //-----------------------------------------------
1520 ::rtl::OUString
OWriteStream_Impl::GetCommonRootPass()
1521 throw ( packages::NoEncryptionException
)
1523 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1525 if ( m_nStorageType
!= PACKAGE_STORAGE
|| !m_pParent
)
1526 throw packages::NoEncryptionException();
1528 return m_pParent
->GetCommonRootPass();
1531 //-----------------------------------------------
1532 void OWriteStream_Impl::InputStreamDisposed( OInputCompStream
* pStream
)
1534 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() );
1535 m_aInputStreamsList
.remove( pStream
);
1538 //-----------------------------------------------
1539 void OWriteStream_Impl::CreateReadonlyCopyBasedOnData( const uno::Reference
< io::XInputStream
>& xDataToCopy
, const uno::Sequence
< beans::PropertyValue
>& aProps
, sal_Bool
, uno::Reference
< io::XStream
>& xTargetStream
)
1541 uno::Reference
< io::XStream
> xTempFile
;
1542 if ( !xTargetStream
.is() )
1543 xTempFile
= uno::Reference
< io::XStream
>(
1544 m_xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
1547 xTempFile
= xTargetStream
;
1549 uno::Reference
< io::XSeekable
> xTempSeek( xTempFile
, uno::UNO_QUERY
);
1550 if ( !xTempSeek
.is() )
1551 throw uno::RuntimeException(); // TODO
1553 uno::Reference
< io::XOutputStream
> xTempOut
= xTempFile
->getOutputStream();
1554 if ( !xTempOut
.is() )
1555 throw uno::RuntimeException();
1557 if ( xDataToCopy
.is() )
1558 ::comphelper::OStorageHelper::CopyInputToOutput( xDataToCopy
, xTempOut
);
1560 xTempOut
->closeOutput();
1561 xTempSeek
->seek( 0 );
1563 uno::Reference
< io::XInputStream
> xInStream
= xTempFile
->getInputStream();
1564 if ( !xInStream
.is() )
1565 throw io::IOException();
1567 // TODO: remember last state of m_bUseCommonPass
1568 if ( !xTargetStream
.is() )
1569 xTargetStream
= uno::Reference
< io::XStream
> (
1570 static_cast< ::cppu::OWeakObject
* >(
1571 new OInputSeekStream( xInStream
, InsertOwnProps( aProps
, m_bUseCommonPass
), m_nStorageType
) ),
1572 uno::UNO_QUERY_THROW
);
1575 //-----------------------------------------------
1576 void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference
< io::XStream
>& xTargetStream
)
1578 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() );
1580 OSL_ENSURE( m_xPackageStream
.is(), "The source stream for copying is incomplete!\n" );
1581 if ( !m_xPackageStream
.is() )
1582 throw uno::RuntimeException();
1584 uno::Reference
< io::XInputStream
> xDataToCopy
;
1585 if ( IsEncrypted() )
1587 // an encrypted stream must contain input stream
1588 ::rtl::OUString aGlobalPass
;
1591 aGlobalPass
= GetCommonRootPass();
1593 catch( packages::NoEncryptionException
& aNoEncryptionException
)
1595 AddLog( aNoEncryptionException
.Message
);
1596 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"No Element" ) ) );
1598 throw packages::WrongPasswordException();
1601 GetCopyOfLastCommit( xTargetStream
, aGlobalPass
);
1605 xDataToCopy
= m_xPackageStream
->getDataStream();
1607 // in case of new inserted package stream it is possible that input stream still was not set
1608 GetStreamProperties();
1610 CreateReadonlyCopyBasedOnData( xDataToCopy
, m_aProps
, m_bUseCommonPass
, xTargetStream
);
1614 //-----------------------------------------------
1615 void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference
< io::XStream
>& xTargetStream
, const ::rtl::OUString
& aPass
)
1617 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() );
1619 OSL_ENSURE( m_xPackageStream
.is(), "The source stream for copying is incomplete!\n" );
1620 if ( !m_xPackageStream
.is() )
1621 throw uno::RuntimeException();
1623 if ( !IsEncrypted() )
1624 throw packages::NoEncryptionException();
1626 uno::Reference
< io::XInputStream
> xDataToCopy
;
1628 if ( m_bHasCachedPassword
)
1630 // TODO: introduce last commited cashed password information and use it here
1631 // that means "use common pass" also should be remembered on flash
1632 uno::Sequence
< sal_Int8
> aNewKey
= ::package::MakeKeyFromPass( aPass
, sal_True
);
1633 uno::Sequence
< sal_Int8
> aOldKey
= ::package::MakeKeyFromPass( aPass
, sal_False
);
1635 uno::Reference
< beans::XPropertySet
> xProps( m_xPackageStream
, uno::UNO_QUERY
);
1637 throw uno::RuntimeException();
1639 sal_Bool bEncr
= sal_False
;
1640 xProps
->getPropertyValue( ::rtl::OUString::createFromAscii( "Encrypted" ) ) >>= bEncr
;
1642 throw packages::NoEncryptionException();
1644 uno::Sequence
< sal_Int8
> aEncrKey
;
1645 xProps
->getPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ) ) >>= aEncrKey
;
1646 if ( !SequencesEqual( aNewKey
, aEncrKey
) && !SequencesEqual( aOldKey
, aEncrKey
) )
1647 throw packages::WrongPasswordException();
1649 // the correct key must be set already
1650 xDataToCopy
= m_xPackageStream
->getDataStream();
1654 uno::Reference
< beans::XPropertySet
> xPropertySet( m_xPackageStream
, uno::UNO_QUERY
);
1655 SetEncryptionKeyProperty_Impl( xPropertySet
, ::package::MakeKeyFromPass( aPass
, sal_True
) );
1658 xDataToCopy
= m_xPackageStream
->getDataStream();
1660 if ( !xDataToCopy
.is() )
1662 OSL_ENSURE( sal_False
, "Encrypted ZipStream must already have input stream inside!\n" );
1663 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1666 catch( packages::WrongPasswordException
& aWrongPasswordException
)
1668 SetEncryptionKeyProperty_Impl( xPropertySet
, ::package::MakeKeyFromPass( aPass
, sal_False
) );
1670 xDataToCopy
= m_xPackageStream
->getDataStream();
1672 if ( !xDataToCopy
.is() )
1674 OSL_ENSURE( sal_False
, "Encrypted ZipStream must already have input stream inside!\n" );
1675 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1676 AddLog( aWrongPasswordException
.Message
);
1677 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
1681 catch( uno::Exception
& aException
)
1683 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1684 AddLog( aException
.Message
);
1685 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
1689 catch( uno::Exception
& aException
)
1691 OSL_ENSURE( sal_False
, "Can't open encrypted stream!\n" );
1692 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1693 AddLog( aException
.Message
);
1694 AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
1698 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1701 // in case of new inserted package stream it is possible that input stream still was not set
1702 GetStreamProperties();
1704 CreateReadonlyCopyBasedOnData( xDataToCopy
, m_aProps
, m_bUseCommonPass
, xTargetStream
);
1707 //-----------------------------------------------
1708 void OWriteStream_Impl::CommitStreamRelInfo( const uno::Reference
< embed::XStorage
>& xRelStorage
, const ::rtl::OUString
& aOrigStreamName
, const ::rtl::OUString
& aNewStreamName
)
1710 // at this point of time the old stream must be already cleaned
1711 OSL_ENSURE( m_nStorageType
== OFOPXML_STORAGE
, "The method should be used only with OFOPXML format!\n" );
1713 if ( m_nStorageType
== OFOPXML_STORAGE
)
1715 OSL_ENSURE( aOrigStreamName
.getLength() && aNewStreamName
.getLength() && xRelStorage
.is(),
1716 "Wrong relation persistence information is provided!\n" );
1718 if ( !xRelStorage
.is() || !aOrigStreamName
.getLength() || !aNewStreamName
.getLength() )
1719 throw uno::RuntimeException();
1721 if ( m_nRelInfoStatus
== RELINFO_BROKEN
|| m_nRelInfoStatus
== RELINFO_CHANGED_BROKEN
)
1722 throw io::IOException(); // TODO:
1724 ::rtl::OUString aOrigRelStreamName
= aOrigStreamName
;
1725 aOrigRelStreamName
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
1727 ::rtl::OUString aNewRelStreamName
= aNewStreamName
;
1728 aNewRelStreamName
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
1730 sal_Bool bRenamed
= !aOrigRelStreamName
.equals( aNewRelStreamName
);
1731 if ( m_nRelInfoStatus
== RELINFO_CHANGED
1732 || m_nRelInfoStatus
== RELINFO_CHANGED_STREAM_READ
1733 || m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1735 if ( bRenamed
&& xRelStorage
->hasByName( aOrigRelStreamName
) )
1736 xRelStorage
->removeElement( aOrigRelStreamName
);
1738 if ( m_nRelInfoStatus
== RELINFO_CHANGED
)
1740 if ( m_aNewRelInfo
.getLength() )
1742 uno::Reference
< io::XStream
> xRelsStream
=
1743 xRelStorage
->openStreamElement( aNewRelStreamName
,
1744 embed::ElementModes::TRUNCATE
| embed::ElementModes::READWRITE
);
1746 uno::Reference
< io::XOutputStream
> xOutStream
= xRelsStream
->getOutputStream();
1747 if ( !xOutStream
.is() )
1748 throw uno::RuntimeException();
1750 ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence( xOutStream
, m_aNewRelInfo
, m_xFactory
);
1752 // set the mediatype
1753 uno::Reference
< beans::XPropertySet
> xPropSet( xRelsStream
, uno::UNO_QUERY_THROW
);
1754 xPropSet
->setPropertyValue(
1755 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1756 uno::makeAny( ::rtl::OUString(
1757 RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
1759 m_nRelInfoStatus
= RELINFO_READ
;
1762 else if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM_READ
1763 || m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1765 uno::Reference
< io::XStream
> xRelsStream
=
1766 xRelStorage
->openStreamElement( aNewRelStreamName
,
1767 embed::ElementModes::TRUNCATE
| embed::ElementModes::READWRITE
);
1769 uno::Reference
< io::XOutputStream
> xOutputStream
= xRelsStream
->getOutputStream();
1770 if ( !xOutputStream
.is() )
1771 throw uno::RuntimeException();
1773 uno::Reference
< io::XSeekable
> xSeek( m_xNewRelInfoStream
, uno::UNO_QUERY_THROW
);
1775 ::comphelper::OStorageHelper::CopyInputToOutput( m_xNewRelInfoStream
, xOutputStream
);
1778 // set the mediatype
1779 uno::Reference
< beans::XPropertySet
> xPropSet( xRelsStream
, uno::UNO_QUERY_THROW
);
1780 xPropSet
->setPropertyValue(
1781 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1782 uno::makeAny( ::rtl::OUString(
1783 RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
1785 if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1786 m_nRelInfoStatus
= RELINFO_NO_INIT
;
1789 // the information is already parsed and the stream is stored, no need in temporary stream any more
1790 m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
1791 m_nRelInfoStatus
= RELINFO_READ
;
1795 // the original stream makes no sence after this step
1796 m_xOrigRelInfoStream
= m_xNewRelInfoStream
;
1797 m_aOrigRelInfo
= m_aNewRelInfo
;
1798 m_bOrigRelInfoBroken
= sal_False
;
1799 m_aNewRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
1800 m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
1804 // the stream is not changed but it might be renamed
1805 if ( bRenamed
&& xRelStorage
->hasByName( aOrigRelStreamName
) )
1806 xRelStorage
->renameElement( aOrigRelStreamName
, aNewRelStreamName
);
1811 //===============================================
1812 // OWriteStream implementation
1813 //===============================================
1815 //-----------------------------------------------
1816 OWriteStream::OWriteStream( OWriteStream_Impl
* pImpl
, sal_Bool bTransacted
)
1818 , m_bInStreamDisconnected( sal_False
)
1819 , m_bInitOnDemand( sal_True
)
1820 , m_nInitPosition( 0 )
1821 , m_bTransacted( bTransacted
)
1823 OSL_ENSURE( pImpl
, "No base implementation!\n" );
1824 OSL_ENSURE( m_pImpl
->m_rMutexRef
.Is(), "No mutex!\n" );
1826 if ( !m_pImpl
|| !m_pImpl
->m_rMutexRef
.Is() )
1827 throw uno::RuntimeException(); // just a disaster
1829 m_pData
= new WSInternalData_Impl( pImpl
->m_rMutexRef
, m_pImpl
->m_nStorageType
);
1832 //-----------------------------------------------
1833 OWriteStream::OWriteStream( OWriteStream_Impl
* pImpl
, uno::Reference
< io::XStream
> xStream
, sal_Bool bTransacted
)
1835 , m_bInStreamDisconnected( sal_False
)
1836 , m_bInitOnDemand( sal_False
)
1837 , m_nInitPosition( 0 )
1838 , m_bTransacted( bTransacted
)
1840 OSL_ENSURE( pImpl
&& xStream
.is(), "No base implementation!\n" );
1841 OSL_ENSURE( m_pImpl
->m_rMutexRef
.Is(), "No mutex!\n" );
1843 if ( !m_pImpl
|| !m_pImpl
->m_rMutexRef
.Is() )
1844 throw uno::RuntimeException(); // just a disaster
1846 m_pData
= new WSInternalData_Impl( pImpl
->m_rMutexRef
, m_pImpl
->m_nStorageType
);
1850 m_xInStream
= xStream
->getInputStream();
1851 m_xOutStream
= xStream
->getOutputStream();
1852 m_xSeekable
= uno::Reference
< io::XSeekable
>( xStream
, uno::UNO_QUERY
);
1853 OSL_ENSURE( m_xInStream
.is() && m_xOutStream
.is() && m_xSeekable
.is(), "Stream implementation is incomplete!\n" );
1857 //-----------------------------------------------
1858 OWriteStream::~OWriteStream()
1861 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
1868 catch( uno::RuntimeException
& aRuntimeException
)
1870 m_pImpl
->AddLog( aRuntimeException
.Message
);
1871 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Quiet exception" ) ) );
1876 if ( m_pData
&& m_pData
->m_pTypeCollection
)
1877 delete m_pData
->m_pTypeCollection
;
1883 //-----------------------------------------------
1884 void OWriteStream::DeInit()
1887 return; // do nothing
1889 if ( m_xSeekable
.is() )
1890 m_nInitPosition
= m_xSeekable
->getPosition();
1892 m_xInStream
= uno::Reference
< io::XInputStream
>();
1893 m_xOutStream
= uno::Reference
< io::XOutputStream
>();
1894 m_xSeekable
= uno::Reference
< io::XSeekable
>();
1895 m_bInitOnDemand
= sal_True
;
1898 //-----------------------------------------------
1899 void OWriteStream::CheckInitOnDemand()
1903 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
1904 throw lang::DisposedException();
1907 if ( m_bInitOnDemand
)
1909 RTL_LOGFILE_CONTEXT( aLog
, "package (mv76033) OWriteStream::CheckInitOnDemand, initializing" );
1910 uno::Reference
< io::XStream
> xStream
= m_pImpl
->GetTempFileAsStream();
1913 m_xInStream
.set( xStream
->getInputStream(), uno::UNO_SET_THROW
);
1914 m_xOutStream
.set( xStream
->getOutputStream(), uno::UNO_SET_THROW
);
1915 m_xSeekable
.set( xStream
, uno::UNO_QUERY_THROW
);
1916 m_xSeekable
->seek( m_nInitPosition
);
1918 m_nInitPosition
= 0;
1919 m_bInitOnDemand
= sal_False
;
1924 //-----------------------------------------------
1925 void OWriteStream::CopyToStreamInternally_Impl( const uno::Reference
< io::XStream
>& xDest
)
1927 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
1929 CheckInitOnDemand();
1931 if ( !m_xInStream
.is() )
1932 throw uno::RuntimeException();
1934 if ( !m_xSeekable
.is() )
1935 throw uno::RuntimeException();
1937 uno::Reference
< beans::XPropertySet
> xDestProps( xDest
, uno::UNO_QUERY
);
1938 if ( !xDestProps
.is() )
1939 throw uno::RuntimeException(); //TODO
1941 uno::Reference
< io::XOutputStream
> xDestOutStream
= xDest
->getOutputStream();
1942 if ( !xDestOutStream
.is() )
1943 throw io::IOException(); // TODO
1945 sal_Int64 nCurPos
= m_xSeekable
->getPosition();
1946 m_xSeekable
->seek( 0 );
1948 uno::Exception eThrown
;
1949 sal_Bool bThrown
= sal_False
;
1951 ::comphelper::OStorageHelper::CopyInputToOutput( m_xInStream
, xDestOutStream
);
1953 catch ( uno::Exception
& e
)
1959 // position-related section below is critical
1960 // if it fails the stream will become invalid
1962 m_xSeekable
->seek( nCurPos
);
1964 catch ( uno::Exception
& aException
)
1966 m_pImpl
->AddLog( aException
.Message
);
1967 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Quiet exception" ) ) );
1969 // TODO: set the stoream in invalid state or dispose
1970 OSL_ENSURE( sal_False
, "The stream become invalid during copiing!\n" );
1971 throw uno::RuntimeException();
1977 // now the properties can be copied
1978 // the order of the properties setting is not important for StorageStream API
1979 ::rtl::OUString aPropName
= ::rtl::OUString::createFromAscii( "Compressed" );
1980 xDestProps
->setPropertyValue( aPropName
, getPropertyValue( aPropName
) );
1981 if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
|| m_pData
->m_nStorageType
== OFOPXML_STORAGE
)
1983 aPropName
= ::rtl::OUString::createFromAscii( "MediaType" );
1984 xDestProps
->setPropertyValue( aPropName
, getPropertyValue( aPropName
) );
1986 if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
)
1988 aPropName
= ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" );
1989 xDestProps
->setPropertyValue( aPropName
, getPropertyValue( aPropName
) );
1994 //-----------------------------------------------
1995 void OWriteStream::ModifyParentUnlockMutex_Impl( ::osl::ResettableMutexGuard
& aGuard
)
1997 if ( m_pImpl
->m_pParent
)
1999 if ( m_pImpl
->m_pParent
->m_pAntiImpl
)
2001 uno::Reference
< util::XModifiable
> xParentModif( (util::XModifiable
*)(m_pImpl
->m_pParent
->m_pAntiImpl
) );
2003 xParentModif
->setModified( sal_True
);
2006 m_pImpl
->m_pParent
->m_bIsModified
= sal_True
;
2010 //-----------------------------------------------
2011 uno::Any SAL_CALL
OWriteStream::queryInterface( const uno::Type
& rType
)
2012 throw( uno::RuntimeException
)
2016 // common interfaces
2017 aReturn
<<= ::cppu::queryInterface
2019 , static_cast<lang::XTypeProvider
*> ( this )
2020 , static_cast<io::XInputStream
*> ( this )
2021 , static_cast<io::XOutputStream
*> ( this )
2022 , static_cast<io::XStream
*> ( this )
2023 , static_cast<embed::XExtendedStorageStream
*> ( this )
2024 , static_cast<io::XSeekable
*> ( this )
2025 , static_cast<io::XTruncate
*> ( this )
2026 , static_cast<lang::XComponent
*> ( this )
2027 , static_cast<beans::XPropertySet
*> ( this ) );
2029 if ( aReturn
.hasValue() == sal_True
)
2032 if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
)
2034 aReturn
<<= ::cppu::queryInterface
2036 , static_cast<embed::XEncryptionProtectedSource
*> ( this ) );
2038 else if ( m_pData
->m_nStorageType
== OFOPXML_STORAGE
)
2040 aReturn
<<= ::cppu::queryInterface
2042 , static_cast<embed::XRelationshipAccess
*> ( this ) );
2045 if ( aReturn
.hasValue() == sal_True
)
2048 if ( m_bTransacted
)
2050 aReturn
<<= ::cppu::queryInterface
2052 , static_cast<embed::XTransactedObject
*> ( this )
2053 , static_cast<embed::XTransactionBroadcaster
*> ( this ) );
2055 if ( aReturn
.hasValue() == sal_True
)
2059 return OWeakObject::queryInterface( rType
);
2062 //-----------------------------------------------
2063 void SAL_CALL
OWriteStream::acquire() throw()
2065 OWeakObject::acquire();
2068 //-----------------------------------------------
2069 void SAL_CALL
OWriteStream::release() throw()
2071 OWeakObject::release();
2074 //-----------------------------------------------
2075 uno::Sequence
< uno::Type
> SAL_CALL
OWriteStream::getTypes()
2076 throw( uno::RuntimeException
)
2078 if ( m_pData
->m_pTypeCollection
== NULL
)
2080 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2082 if ( m_pData
->m_pTypeCollection
== NULL
)
2084 if ( m_bTransacted
)
2086 if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
)
2088 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
2089 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
2090 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
2091 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
2092 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
2093 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
2094 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
2095 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
2096 , ::getCppuType( ( const uno::Reference
< embed::XEncryptionProtectedSource
>* )NULL
)
2097 , ::getCppuType( ( const uno::Reference
< embed::XExtendedStorageStream
>* )NULL
)
2098 , ::getCppuType( ( const uno::Reference
< embed::XTransactedObject
>* )NULL
)
2099 , ::getCppuType( ( const uno::Reference
< embed::XTransactionBroadcaster
>* )NULL
)
2100 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
2102 else if ( m_pData
->m_nStorageType
== OFOPXML_STORAGE
)
2104 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
2105 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
2106 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
2107 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
2108 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
2109 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
2110 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
2111 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
2112 , ::getCppuType( ( const uno::Reference
< embed::XRelationshipAccess
>* )NULL
)
2113 , ::getCppuType( ( const uno::Reference
< embed::XExtendedStorageStream
>* )NULL
)
2114 , ::getCppuType( ( const uno::Reference
< embed::XTransactedObject
>* )NULL
)
2115 , ::getCppuType( ( const uno::Reference
< embed::XTransactionBroadcaster
>* )NULL
)
2116 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
2118 else // if ( m_pData->m_nStorageType == ZIP_STORAGE )
2120 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
2121 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
2122 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
2123 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
2124 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
2125 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
2126 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
2127 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
2128 , ::getCppuType( ( const uno::Reference
< embed::XExtendedStorageStream
>* )NULL
)
2129 , ::getCppuType( ( const uno::Reference
< embed::XTransactedObject
>* )NULL
)
2130 , ::getCppuType( ( const uno::Reference
< embed::XTransactionBroadcaster
>* )NULL
)
2131 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
2136 if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
)
2138 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
2139 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
2140 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
2141 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
2142 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
2143 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
2144 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
2145 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
2146 , ::getCppuType( ( const uno::Reference
< embed::XEncryptionProtectedSource
>* )NULL
)
2147 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
2149 else if ( m_pData
->m_nStorageType
== OFOPXML_STORAGE
)
2151 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
2152 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
2153 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
2154 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
2155 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
2156 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
2157 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
2158 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
2159 , ::getCppuType( ( const uno::Reference
< embed::XRelationshipAccess
>* )NULL
)
2160 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
2162 else // if ( m_pData->m_nStorageType == ZIP_STORAGE )
2164 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
2165 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
2166 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
2167 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
2168 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
2169 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
2170 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
2171 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
2172 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
2178 return m_pData
->m_pTypeCollection
->getTypes() ;
2181 //-----------------------------------------------
2182 uno::Sequence
< sal_Int8
> SAL_CALL
OWriteStream::getImplementationId()
2183 throw( uno::RuntimeException
)
2185 static ::cppu::OImplementationId
* pID
= NULL
;
2189 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() ) ;
2193 static ::cppu::OImplementationId
aID( sal_False
) ;
2198 return pID
->getImplementationId() ;
2202 //-----------------------------------------------
2203 sal_Int32 SAL_CALL
OWriteStream::readBytes( uno::Sequence
< sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
2204 throw ( io::NotConnectedException
,
2205 io::BufferSizeExceededException
,
2207 uno::RuntimeException
)
2209 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2211 CheckInitOnDemand();
2215 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2216 throw lang::DisposedException();
2219 if ( !m_xInStream
.is() )
2220 throw io::NotConnectedException();
2222 return m_xInStream
->readBytes( aData
, nBytesToRead
);
2225 //-----------------------------------------------
2226 sal_Int32 SAL_CALL
OWriteStream::readSomeBytes( uno::Sequence
< sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
2227 throw ( io::NotConnectedException
,
2228 io::BufferSizeExceededException
,
2230 uno::RuntimeException
)
2232 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2234 CheckInitOnDemand();
2238 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2239 throw lang::DisposedException();
2242 if ( !m_xInStream
.is() )
2243 throw io::NotConnectedException();
2245 return m_xInStream
->readSomeBytes( aData
, nMaxBytesToRead
);
2248 //-----------------------------------------------
2249 void SAL_CALL
OWriteStream::skipBytes( sal_Int32 nBytesToSkip
)
2250 throw ( io::NotConnectedException
,
2251 io::BufferSizeExceededException
,
2253 uno::RuntimeException
)
2255 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2257 CheckInitOnDemand();
2261 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2262 throw lang::DisposedException();
2265 if ( !m_xInStream
.is() )
2266 throw io::NotConnectedException();
2268 m_xInStream
->skipBytes( nBytesToSkip
);
2271 //-----------------------------------------------
2272 sal_Int32 SAL_CALL
OWriteStream::available( )
2273 throw ( io::NotConnectedException
,
2275 uno::RuntimeException
)
2277 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2279 CheckInitOnDemand();
2283 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2284 throw lang::DisposedException();
2287 if ( !m_xInStream
.is() )
2288 throw io::NotConnectedException();
2290 return m_xInStream
->available();
2294 //-----------------------------------------------
2295 void SAL_CALL
OWriteStream::closeInput( )
2296 throw ( io::NotConnectedException
,
2298 uno::RuntimeException
)
2300 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2304 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2305 throw lang::DisposedException();
2308 if ( !m_bInitOnDemand
&& ( m_bInStreamDisconnected
|| !m_xInStream
.is() ) )
2309 throw io::NotConnectedException();
2311 // the input part of the stream stays open for internal purposes ( to allow reading during copiing )
2312 // since it can not be reopened until output part is closed, it will be closed with output part.
2313 m_bInStreamDisconnected
= sal_True
;
2314 // m_xInStream->closeInput();
2315 // m_xInStream = uno::Reference< io::XInputStream >();
2317 if ( !m_xOutStream
.is() )
2321 //-----------------------------------------------
2322 uno::Reference
< io::XInputStream
> SAL_CALL
OWriteStream::getInputStream()
2323 throw ( uno::RuntimeException
)
2325 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2329 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2330 throw lang::DisposedException();
2333 if ( !m_bInitOnDemand
&& ( m_bInStreamDisconnected
|| !m_xInStream
.is() ) )
2334 return uno::Reference
< io::XInputStream
>();
2336 return uno::Reference
< io::XInputStream
>( static_cast< io::XInputStream
* >( this ), uno::UNO_QUERY
);
2339 //-----------------------------------------------
2340 uno::Reference
< io::XOutputStream
> SAL_CALL
OWriteStream::getOutputStream()
2341 throw ( uno::RuntimeException
)
2343 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2345 CheckInitOnDemand();
2349 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2350 throw lang::DisposedException();
2353 if ( !m_xOutStream
.is() )
2354 return uno::Reference
< io::XOutputStream
>();
2356 return uno::Reference
< io::XOutputStream
>( static_cast< io::XOutputStream
* >( this ), uno::UNO_QUERY
);
2359 //-----------------------------------------------
2360 void SAL_CALL
OWriteStream::writeBytes( const uno::Sequence
< sal_Int8
>& aData
)
2361 throw ( io::NotConnectedException
,
2362 io::BufferSizeExceededException
,
2364 uno::RuntimeException
)
2366 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2368 // the write method makes initialization itself, since it depends from the aData length
2369 // NO CheckInitOnDemand()!
2373 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2374 throw lang::DisposedException();
2377 if ( !m_bInitOnDemand
)
2379 if ( !m_xOutStream
.is() || !m_xSeekable
.is())
2380 throw io::NotConnectedException();
2382 if ( m_pImpl
->m_xCacheStream
.is() )
2384 // check whether the cache should be turned off
2385 sal_Int64 nPos
= m_xSeekable
->getPosition();
2386 if ( nPos
+ aData
.getLength() > MAX_STORCACHE_SIZE
)
2388 // disconnect the cache and copy the data to the temporary file
2389 m_xSeekable
->seek( 0 );
2391 // it is enough to copy the cached stream, the cache should already contain everything
2392 if ( m_pImpl
->GetFilledTempFileIfNo( m_xInStream
).getLength() )
2395 // the last position is known and it is differs from the current stream position
2396 m_nInitPosition
= nPos
;
2402 if ( m_bInitOnDemand
)
2404 RTL_LOGFILE_CONTEXT( aLog
, "package (mv76033) OWriteStream::CheckInitOnDemand, initializing" );
2405 uno::Reference
< io::XStream
> xStream
= m_pImpl
->GetTempFileAsStream();
2408 m_xInStream
.set( xStream
->getInputStream(), uno::UNO_SET_THROW
);
2409 m_xOutStream
.set( xStream
->getOutputStream(), uno::UNO_SET_THROW
);
2410 m_xSeekable
.set( xStream
, uno::UNO_QUERY_THROW
);
2411 m_xSeekable
->seek( m_nInitPosition
);
2413 m_nInitPosition
= 0;
2414 m_bInitOnDemand
= sal_False
;
2419 if ( !m_xOutStream
.is() )
2420 throw io::NotConnectedException();
2422 m_xOutStream
->writeBytes( aData
);
2423 m_pImpl
->m_bHasDataToFlush
= sal_True
;
2425 ModifyParentUnlockMutex_Impl( aGuard
);
2428 //-----------------------------------------------
2429 void SAL_CALL
OWriteStream::flush()
2430 throw ( io::NotConnectedException
,
2431 io::BufferSizeExceededException
,
2433 uno::RuntimeException
)
2435 // In case stream is flushed it's current version becomes visible
2436 // to the parent storage. Usually parent storage flushes the stream
2437 // during own commit but a user can explicitly flush the stream
2438 // so the changes will be available through cloning functionality.
2440 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2444 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2445 throw lang::DisposedException();
2448 if ( !m_bInitOnDemand
)
2450 if ( !m_xOutStream
.is() )
2451 throw io::NotConnectedException();
2453 m_xOutStream
->flush();
2458 //-----------------------------------------------
2459 void OWriteStream::CloseOutput_Impl()
2461 // all the checks must be done in calling method
2463 m_xOutStream
->closeOutput();
2464 m_xOutStream
= uno::Reference
< io::XOutputStream
>();
2466 if ( !m_bInitOnDemand
)
2468 // after the stream is disposed it can be commited
2469 // so transport correct size property
2470 if ( !m_xSeekable
.is() )
2471 throw uno::RuntimeException();
2473 for ( sal_Int32 nInd
= 0; nInd
< m_pImpl
->m_aProps
.getLength(); nInd
++ )
2475 if ( m_pImpl
->m_aProps
[nInd
].Name
.equalsAscii( "Size" ) )
2476 m_pImpl
->m_aProps
[nInd
].Value
<<= ((sal_Int32
)m_xSeekable
->getLength());
2481 //-----------------------------------------------
2482 void SAL_CALL
OWriteStream::closeOutput()
2483 throw ( io::NotConnectedException
,
2484 io::BufferSizeExceededException
,
2486 uno::RuntimeException
)
2488 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2490 CheckInitOnDemand();
2494 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2495 throw lang::DisposedException();
2498 if ( !m_xOutStream
.is() )
2499 throw io::NotConnectedException();
2503 if ( m_bInStreamDisconnected
|| !m_xInStream
.is() )
2507 //-----------------------------------------------
2508 void SAL_CALL
OWriteStream::seek( sal_Int64 location
)
2509 throw ( lang::IllegalArgumentException
,
2511 uno::RuntimeException
)
2513 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2515 CheckInitOnDemand();
2519 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2520 throw lang::DisposedException();
2523 if ( !m_xSeekable
.is() )
2524 throw uno::RuntimeException();
2526 m_xSeekable
->seek( location
);
2529 //-----------------------------------------------
2530 sal_Int64 SAL_CALL
OWriteStream::getPosition()
2531 throw ( io::IOException
,
2532 uno::RuntimeException
)
2534 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2536 CheckInitOnDemand();
2540 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2541 throw lang::DisposedException();
2544 if ( !m_xSeekable
.is() )
2545 throw uno::RuntimeException();
2547 return m_xSeekable
->getPosition();
2550 //-----------------------------------------------
2551 sal_Int64 SAL_CALL
OWriteStream::getLength()
2552 throw ( io::IOException
,
2553 uno::RuntimeException
)
2555 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2557 CheckInitOnDemand();
2561 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2562 throw lang::DisposedException();
2565 if ( !m_xSeekable
.is() )
2566 throw uno::RuntimeException();
2568 return m_xSeekable
->getLength();
2571 //-----------------------------------------------
2572 void SAL_CALL
OWriteStream::truncate()
2573 throw ( io::IOException
,
2574 uno::RuntimeException
)
2576 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2578 CheckInitOnDemand();
2582 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2583 throw lang::DisposedException();
2586 if ( !m_xOutStream
.is() )
2587 throw uno::RuntimeException();
2589 uno::Reference
< io::XTruncate
> xTruncate( m_xOutStream
, uno::UNO_QUERY
);
2591 if ( !xTruncate
.is() )
2593 OSL_ENSURE( sal_False
, "The output stream must support XTruncate interface!\n" );
2594 throw uno::RuntimeException();
2597 xTruncate
->truncate();
2599 m_pImpl
->m_bHasDataToFlush
= sal_True
;
2601 ModifyParentUnlockMutex_Impl( aGuard
);
2604 //-----------------------------------------------
2605 void SAL_CALL
OWriteStream::dispose()
2606 throw ( uno::RuntimeException
)
2608 // should be an internal method since it can be called only from parent storage
2610 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2614 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2615 throw lang::DisposedException();
2618 if ( m_xOutStream
.is() )
2621 if ( m_xInStream
.is() )
2623 m_xInStream
->closeInput();
2624 m_xInStream
= uno::Reference
< io::XInputStream
>();
2627 m_pImpl
->m_pAntiImpl
= NULL
;
2629 if ( !m_bInitOnDemand
)
2633 if ( !m_bTransacted
)
2639 // throw away all the changes
2643 catch( uno::Exception
& aException
)
2645 m_pImpl
->AddLog( aException
.Message
);
2646 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
2648 uno::Any
aCaught( ::cppu::getCaughtException() );
2649 throw lang::WrappedTargetRuntimeException(
2650 ::rtl::OUString::createFromAscii( "Can not commit/revert the storage!\n" ),
2651 uno::Reference
< uno::XInterface
>( static_cast< OWeakObject
* >( this ),
2660 // the listener might try to get rid of parent storage, and the storage would delete this object;
2661 // for now the listener is just notified at the end of the method to workaround the problem
2662 // in future a more elegant way should be found
2664 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
2665 m_pData
->m_aListenersContainer
.disposeAndClear( aSource
);
2668 //-----------------------------------------------
2669 void SAL_CALL
OWriteStream::addEventListener(
2670 const uno::Reference
< lang::XEventListener
>& xListener
)
2671 throw ( uno::RuntimeException
)
2673 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2677 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2678 throw lang::DisposedException();
2681 m_pData
->m_aListenersContainer
.addInterface( ::getCppuType((const uno::Reference
< lang::XEventListener
>*)0),
2685 //-----------------------------------------------
2686 void SAL_CALL
OWriteStream::removeEventListener(
2687 const uno::Reference
< lang::XEventListener
>& xListener
)
2688 throw ( uno::RuntimeException
)
2690 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2694 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2695 throw lang::DisposedException();
2698 m_pData
->m_aListenersContainer
.removeInterface( ::getCppuType((const uno::Reference
< lang::XEventListener
>*)0),
2702 //-----------------------------------------------
2703 void SAL_CALL
OWriteStream::setEncryptionPassword( const ::rtl::OUString
& aPass
)
2704 throw ( uno::RuntimeException
,
2707 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2709 CheckInitOnDemand();
2713 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2714 throw lang::DisposedException();
2717 OSL_ENSURE( m_pImpl
->m_xPackageStream
.is(), "No package stream is set!\n" );
2719 m_pImpl
->SetEncryptedWithPass( aPass
);
2721 ModifyParentUnlockMutex_Impl( aGuard
);
2724 //-----------------------------------------------
2725 void SAL_CALL
OWriteStream::removeEncryption()
2726 throw ( uno::RuntimeException
,
2729 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2731 CheckInitOnDemand();
2735 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2736 throw lang::DisposedException();
2739 OSL_ENSURE( m_pImpl
->m_xPackageStream
.is(), "No package stream is set!\n" );
2741 m_pImpl
->SetDecrypted();
2743 ModifyParentUnlockMutex_Impl( aGuard
);
2746 //-----------------------------------------------
2747 sal_Bool SAL_CALL
OWriteStream::hasByID( const ::rtl::OUString
& sID
)
2748 throw ( io::IOException
,
2749 uno::RuntimeException
)
2751 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2755 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2756 throw lang::DisposedException();
2759 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2760 throw uno::RuntimeException();
2764 getRelationshipByID( sID
);
2767 catch( container::NoSuchElementException
& aNoSuchElementException
)
2769 m_pImpl
->AddLog( aNoSuchElementException
.Message
);
2770 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"No Element" ) ) );
2776 //-----------------------------------------------
2777 ::rtl::OUString SAL_CALL
OWriteStream::getTargetByID( const ::rtl::OUString
& sID
)
2778 throw ( container::NoSuchElementException
,
2780 uno::RuntimeException
)
2782 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2786 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2787 throw lang::DisposedException();
2790 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2791 throw uno::RuntimeException();
2793 uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
2794 for ( sal_Int32 nInd
= 0; nInd
< aSeq
.getLength(); nInd
++ )
2795 if ( aSeq
[nInd
].First
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Target" ) ) )
2796 return aSeq
[nInd
].Second
;
2798 return ::rtl::OUString();
2801 //-----------------------------------------------
2802 ::rtl::OUString SAL_CALL
OWriteStream::getTypeByID( const ::rtl::OUString
& sID
)
2803 throw ( container::NoSuchElementException
,
2805 uno::RuntimeException
)
2807 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2811 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2812 throw lang::DisposedException();
2815 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2816 throw uno::RuntimeException();
2818 uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
2819 for ( sal_Int32 nInd
= 0; nInd
< aSeq
.getLength(); nInd
++ )
2820 if ( aSeq
[nInd
].First
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
2821 return aSeq
[nInd
].Second
;
2823 return ::rtl::OUString();
2826 //-----------------------------------------------
2827 uno::Sequence
< beans::StringPair
> SAL_CALL
OWriteStream::getRelationshipByID( const ::rtl::OUString
& sID
)
2828 throw ( container::NoSuchElementException
,
2830 uno::RuntimeException
)
2832 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2836 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2837 throw lang::DisposedException();
2840 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2841 throw uno::RuntimeException();
2843 // TODO/LATER: in future the unification of the ID could be checked
2844 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
2845 for ( sal_Int32 nInd1
= 0; nInd1
< aSeq
.getLength(); nInd1
++ )
2846 for ( sal_Int32 nInd2
= 0; nInd2
< aSeq
[nInd1
].getLength(); nInd2
++ )
2847 if ( aSeq
[nInd1
][nInd2
].First
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
2849 if ( aSeq
[nInd1
][nInd2
].Second
.equals( sID
) )
2854 throw container::NoSuchElementException();
2857 //-----------------------------------------------
2858 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OWriteStream::getRelationshipsByType( const ::rtl::OUString
& sType
)
2859 throw ( io::IOException
,
2860 uno::RuntimeException
)
2862 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2866 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2867 throw lang::DisposedException();
2870 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2871 throw uno::RuntimeException();
2873 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aResult
;
2874 sal_Int32 nEntriesNum
= 0;
2876 // TODO/LATER: in future the unification of the ID could be checked
2877 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
2878 for ( sal_Int32 nInd1
= 0; nInd1
< aSeq
.getLength(); nInd1
++ )
2879 for ( sal_Int32 nInd2
= 0; nInd2
< aSeq
[nInd1
].getLength(); nInd2
++ )
2880 if ( aSeq
[nInd1
][nInd2
].First
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
2882 if ( aSeq
[nInd1
][nInd2
].Second
.equals( sType
) )
2884 aResult
.realloc( nEntriesNum
);
2885 aResult
[nEntriesNum
-1] = aSeq
[nInd1
];
2893 //-----------------------------------------------
2894 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OWriteStream::getAllRelationships()
2895 throw (io::IOException
, uno::RuntimeException
)
2897 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2901 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2902 throw lang::DisposedException();
2905 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2906 throw uno::RuntimeException();
2908 return m_pImpl
->GetAllRelationshipsIfAny();
2911 //-----------------------------------------------
2912 void SAL_CALL
OWriteStream::insertRelationshipByID( const ::rtl::OUString
& sID
, const uno::Sequence
< beans::StringPair
>& aEntry
, ::sal_Bool bReplace
)
2913 throw ( container::ElementExistException
,
2915 uno::RuntimeException
)
2917 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2921 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2922 throw lang::DisposedException();
2925 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2926 throw uno::RuntimeException();
2928 ::rtl::OUString
aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
2930 sal_Int32 nIDInd
= -1;
2932 // TODO/LATER: in future the unification of the ID could be checked
2933 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
2934 for ( sal_Int32 nInd1
= 0; nInd1
< aSeq
.getLength(); nInd1
++ )
2935 for ( sal_Int32 nInd2
= 0; nInd2
< aSeq
[nInd1
].getLength(); nInd2
++ )
2936 if ( aSeq
[nInd1
][nInd2
].First
.equals( aIDTag
) )
2938 if ( aSeq
[nInd1
][nInd2
].Second
.equals( sID
) )
2944 if ( nIDInd
== -1 || bReplace
)
2948 nIDInd
= aSeq
.getLength();
2949 aSeq
.realloc( nIDInd
+ 1 );
2952 aSeq
[nIDInd
].realloc( aEntry
.getLength() + 1 );
2954 aSeq
[nIDInd
][0].First
= aIDTag
;
2955 aSeq
[nIDInd
][0].Second
= sID
;
2956 sal_Int32 nIndTarget
= 1;
2957 for ( sal_Int32 nIndOrig
= 0;
2958 nIndOrig
< aEntry
.getLength();
2961 if ( !aEntry
[nIndOrig
].First
.equals( aIDTag
) )
2962 aSeq
[nIDInd
][nIndTarget
++] = aEntry
[nIndOrig
];
2965 aSeq
[nIDInd
].realloc( nIndTarget
);
2968 throw container::ElementExistException(); // TODO
2971 m_pImpl
->m_aNewRelInfo
= aSeq
;
2972 m_pImpl
->m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
2973 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
2976 //-----------------------------------------------
2977 void SAL_CALL
OWriteStream::removeRelationshipByID( const ::rtl::OUString
& sID
)
2978 throw ( container::NoSuchElementException
,
2980 uno::RuntimeException
)
2982 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2986 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
2987 throw lang::DisposedException();
2990 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2991 throw uno::RuntimeException();
2993 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
2994 for ( sal_Int32 nInd1
= 0; nInd1
< aSeq
.getLength(); nInd1
++ )
2995 for ( sal_Int32 nInd2
= 0; nInd2
< aSeq
[nInd1
].getLength(); nInd2
++ )
2996 if ( aSeq
[nInd1
][nInd2
].First
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
2998 if ( aSeq
[nInd1
][nInd2
].Second
.equals( sID
) )
3000 sal_Int32 nLength
= aSeq
.getLength();
3001 aSeq
[nInd1
] = aSeq
[nLength
-1];
3002 aSeq
.realloc( nLength
- 1 );
3004 m_pImpl
->m_aNewRelInfo
= aSeq
;
3005 m_pImpl
->m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
3006 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
3008 // TODO/LATER: in future the unification of the ID could be checked
3015 throw container::NoSuchElementException();
3018 //-----------------------------------------------
3019 void SAL_CALL
OWriteStream::insertRelationships( const uno::Sequence
< uno::Sequence
< beans::StringPair
> >& aEntries
, ::sal_Bool bReplace
)
3020 throw ( container::ElementExistException
,
3022 uno::RuntimeException
)
3024 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3028 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3029 throw lang::DisposedException();
3032 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
3033 throw uno::RuntimeException();
3035 ::rtl::OUString
aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
3036 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
3037 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aResultSeq( aSeq
.getLength() + aEntries
.getLength() );
3038 sal_Int32 nResultInd
= 0;
3040 for ( sal_Int32 nIndTarget1
= 0; nIndTarget1
< aSeq
.getLength(); nIndTarget1
++ )
3041 for ( sal_Int32 nIndTarget2
= 0; nIndTarget2
< aSeq
[nIndTarget1
].getLength(); nIndTarget2
++ )
3042 if ( aSeq
[nIndTarget1
][nIndTarget2
].First
.equals( aIDTag
) )
3044 sal_Int32 nIndSourceSame
= -1;
3046 for ( sal_Int32 nIndSource1
= 0; nIndSource1
< aEntries
.getLength(); nIndSource1
++ )
3047 for ( sal_Int32 nIndSource2
= 0; nIndSource2
< aEntries
[nIndSource1
].getLength(); nIndSource2
++ )
3049 if ( aEntries
[nIndSource1
][nIndSource2
].First
.equals( aIDTag
) )
3051 if ( aEntries
[nIndSource1
][nIndSource2
].Second
.equals( aSeq
[nIndTarget1
][nIndTarget2
].Second
) )
3054 throw container::ElementExistException();
3056 nIndSourceSame
= nIndSource1
;
3063 if ( nIndSourceSame
== -1 )
3065 // no such element in the provided sequence
3066 aResultSeq
[nResultInd
++] = aSeq
[nIndTarget1
];
3072 for ( sal_Int32 nIndSource1
= 0; nIndSource1
< aEntries
.getLength(); nIndSource1
++ )
3074 aResultSeq
[nResultInd
].realloc( aEntries
[nIndSource1
].getLength() );
3075 sal_Bool bHasID
= sal_False
;
3076 sal_Int32 nResInd2
= 1;
3078 for ( sal_Int32 nIndSource2
= 0; nIndSource2
< aEntries
[nIndSource1
].getLength(); nIndSource2
++ )
3079 if ( aEntries
[nIndSource1
][nIndSource2
].First
.equals( aIDTag
) )
3081 aResultSeq
[nResultInd
][0] = aEntries
[nIndSource1
][nIndSource2
];
3084 else if ( nResInd2
< aResultSeq
[nResultInd
].getLength() )
3085 aResultSeq
[nResultInd
][nResInd2
++] = aEntries
[nIndSource1
][nIndSource2
];
3087 throw io::IOException(); // TODO: illegal relation ( no ID )
3090 throw io::IOException(); // TODO: illegal relations
3095 aResultSeq
.realloc( nResultInd
);
3096 m_pImpl
->m_aNewRelInfo
= aResultSeq
;
3097 m_pImpl
->m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
3098 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
3101 //-----------------------------------------------
3102 void SAL_CALL
OWriteStream::clearRelationships()
3103 throw ( io::IOException
,
3104 uno::RuntimeException
)
3106 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3110 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3111 throw lang::DisposedException();
3114 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
3115 throw uno::RuntimeException();
3117 m_pImpl
->m_aNewRelInfo
.realloc( 0 );
3118 m_pImpl
->m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
3119 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
3122 //-----------------------------------------------
3123 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
OWriteStream::getPropertySetInfo()
3124 throw ( uno::RuntimeException
)
3126 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3129 return uno::Reference
< beans::XPropertySetInfo
>();
3132 //-----------------------------------------------
3133 void SAL_CALL
OWriteStream::setPropertyValue( const ::rtl::OUString
& aPropertyName
, const uno::Any
& aValue
)
3134 throw ( beans::UnknownPropertyException
,
3135 beans::PropertyVetoException
,
3136 lang::IllegalArgumentException
,
3137 lang::WrappedTargetException
,
3138 uno::RuntimeException
)
3140 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3144 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3145 throw lang::DisposedException();
3148 m_pImpl
->GetStreamProperties();
3149 ::rtl::OUString
aCompressedString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) );
3150 ::rtl::OUString
aMediaTypeString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
3151 if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
&& aPropertyName
.equals( aMediaTypeString
) )
3153 // if the "Compressed" property is not set explicitly, the MediaType can change the default value
3154 sal_Bool bCompressedValueFromType
= sal_True
;
3155 ::rtl::OUString aType
;
3158 if ( !m_pImpl
->m_bCompressedSetExplicit
)
3160 if ( aType
.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/jpeg" ) ) )
3161 || aType
.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/png" ) ) )
3162 || aType
.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/gif" ) ) ) )
3163 bCompressedValueFromType
= sal_False
;
3166 for ( sal_Int32 nInd
= 0; nInd
< m_pImpl
->m_aProps
.getLength(); nInd
++ )
3168 if ( aPropertyName
.equals( m_pImpl
->m_aProps
[nInd
].Name
) )
3169 m_pImpl
->m_aProps
[nInd
].Value
= aValue
;
3170 else if ( !m_pImpl
->m_bCompressedSetExplicit
&& aCompressedString
.equals( m_pImpl
->m_aProps
[nInd
].Name
) )
3171 m_pImpl
->m_aProps
[nInd
].Value
<<= bCompressedValueFromType
;
3174 else if ( aPropertyName
.equals( aCompressedString
) )
3176 // if the "Compressed" property is not set explicitly, the MediaType can change the default value
3177 m_pImpl
->m_bCompressedSetExplicit
= sal_True
;
3178 for ( sal_Int32 nInd
= 0; nInd
< m_pImpl
->m_aProps
.getLength(); nInd
++ )
3180 if ( aPropertyName
.equals( m_pImpl
->m_aProps
[nInd
].Name
) )
3181 m_pImpl
->m_aProps
[nInd
].Value
= aValue
;
3184 else if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
3185 && aPropertyName
.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
3187 sal_Bool bUseCommonPass
= sal_False
;
3188 if ( aValue
>>= bUseCommonPass
)
3190 if ( m_bInitOnDemand
&& m_pImpl
->m_bHasInsertedStreamOptimization
)
3192 // the data stream is provided to the packagestream directly
3193 m_pImpl
->m_bUseCommonPass
= bUseCommonPass
;
3195 else if ( bUseCommonPass
)
3197 if ( !m_pImpl
->m_bUseCommonPass
)
3199 m_pImpl
->SetDecrypted();
3200 m_pImpl
->m_bUseCommonPass
= sal_True
;
3204 m_pImpl
->m_bUseCommonPass
= sal_False
;
3207 throw lang::IllegalArgumentException(); //TODO
3209 else if ( m_pData
->m_nStorageType
== OFOPXML_STORAGE
&& aPropertyName
.equals( aMediaTypeString
) )
3211 for ( sal_Int32 nInd
= 0; nInd
< m_pImpl
->m_aProps
.getLength(); nInd
++ )
3213 if ( aPropertyName
.equals( m_pImpl
->m_aProps
[nInd
].Name
) )
3214 m_pImpl
->m_aProps
[nInd
].Value
= aValue
;
3217 else if ( m_pData
->m_nStorageType
== OFOPXML_STORAGE
&& aPropertyName
.equalsAscii( "RelationsInfoStream" ) )
3219 uno::Reference
< io::XInputStream
> xInRelStream
;
3220 if ( ( aValue
>>= xInRelStream
) && xInRelStream
.is() )
3222 uno::Reference
< io::XSeekable
> xSeek( xInRelStream
, uno::UNO_QUERY
);
3225 // currently this is an internal property that is used for optimization
3226 // and the stream must support XSeekable interface
3227 // TODO/LATER: in future it can be changed if property is used from outside
3228 throw lang::IllegalArgumentException(); // TODO
3231 m_pImpl
->m_xNewRelInfoStream
= xInRelStream
;
3232 m_pImpl
->m_aNewRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
3233 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED_STREAM
;
3236 throw lang::IllegalArgumentException(); // TODO
3238 else if ( m_pData
->m_nStorageType
== OFOPXML_STORAGE
&& aPropertyName
.equalsAscii( "RelationsInfo" ) )
3240 if ( aValue
>>= m_pImpl
->m_aNewRelInfo
)
3244 throw lang::IllegalArgumentException(); // TODO
3246 else if ( aPropertyName
.equalsAscii( "Size" ) )
3247 throw beans::PropertyVetoException(); // TODO
3248 else if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
3249 && ( aPropertyName
.equalsAscii( "IsEncrypted" ) || aPropertyName
.equalsAscii( "Encrypted" ) ) )
3250 throw beans::PropertyVetoException(); // TODO
3252 throw beans::UnknownPropertyException(); // TODO
3254 m_pImpl
->m_bHasDataToFlush
= sal_True
;
3255 ModifyParentUnlockMutex_Impl( aGuard
);
3259 //-----------------------------------------------
3260 uno::Any SAL_CALL
OWriteStream::getPropertyValue( const ::rtl::OUString
& aProp
)
3261 throw ( beans::UnknownPropertyException
,
3262 lang::WrappedTargetException
,
3263 uno::RuntimeException
)
3265 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3269 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3270 throw lang::DisposedException();
3273 if ( aProp
.equalsAscii( "RelId" ) )
3275 return uno::makeAny( m_pImpl
->GetNewRelId() );
3278 ::rtl::OUString aPropertyName
;
3279 if ( aProp
.equalsAscii( "IsEncrypted" ) )
3280 aPropertyName
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Encrypted" ) );
3282 aPropertyName
= aProp
;
3284 if ( ( ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
|| m_pData
->m_nStorageType
== OFOPXML_STORAGE
)
3285 && aPropertyName
.equalsAscii( "MediaType" ) )
3286 || m_pData
->m_nStorageType
== PACKAGE_STORAGE
&& aPropertyName
.equalsAscii( "Encrypted" )
3287 || aPropertyName
.equalsAscii( "Compressed" ) )
3289 m_pImpl
->GetStreamProperties();
3291 for ( sal_Int32 nInd
= 0; nInd
< m_pImpl
->m_aProps
.getLength(); nInd
++ )
3293 if ( aPropertyName
.equals( m_pImpl
->m_aProps
[nInd
].Name
) )
3294 return m_pImpl
->m_aProps
[nInd
].Value
;
3297 else if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
3298 && aPropertyName
.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
3299 return uno::makeAny( m_pImpl
->m_bUseCommonPass
);
3300 else if ( aPropertyName
.equalsAscii( "Size" ) )
3302 CheckInitOnDemand();
3304 if ( !m_xSeekable
.is() )
3305 throw uno::RuntimeException();
3307 return uno::makeAny( (sal_Int32
)m_xSeekable
->getLength() );
3310 throw beans::UnknownPropertyException(); // TODO
3314 //-----------------------------------------------
3315 void SAL_CALL
OWriteStream::addPropertyChangeListener(
3316 const ::rtl::OUString
& /*aPropertyName*/,
3317 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/ )
3318 throw ( beans::UnknownPropertyException
,
3319 lang::WrappedTargetException
,
3320 uno::RuntimeException
)
3322 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3326 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3327 throw lang::DisposedException();
3334 //-----------------------------------------------
3335 void SAL_CALL
OWriteStream::removePropertyChangeListener(
3336 const ::rtl::OUString
& /*aPropertyName*/,
3337 const uno::Reference
< beans::XPropertyChangeListener
>& /*aListener*/ )
3338 throw ( beans::UnknownPropertyException
,
3339 lang::WrappedTargetException
,
3340 uno::RuntimeException
)
3342 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3346 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3347 throw lang::DisposedException();
3354 //-----------------------------------------------
3355 void SAL_CALL
OWriteStream::addVetoableChangeListener(
3356 const ::rtl::OUString
& /*PropertyName*/,
3357 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
3358 throw ( beans::UnknownPropertyException
,
3359 lang::WrappedTargetException
,
3360 uno::RuntimeException
)
3362 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3366 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3367 throw lang::DisposedException();
3374 //-----------------------------------------------
3375 void SAL_CALL
OWriteStream::removeVetoableChangeListener(
3376 const ::rtl::OUString
& /*PropertyName*/,
3377 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
3378 throw ( beans::UnknownPropertyException
,
3379 lang::WrappedTargetException
,
3380 uno::RuntimeException
)
3382 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3386 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3387 throw lang::DisposedException();
3393 //____________________________________________________________________________________________________
3394 // XTransactedObject
3395 //____________________________________________________________________________________________________
3397 //-----------------------------------------------
3398 void OWriteStream::BroadcastTransaction( sal_Int8 nMessage
)
3406 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
3409 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3410 throw lang::DisposedException();
3413 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
3415 ::cppu::OInterfaceContainerHelper
* pContainer
=
3416 m_pData
->m_aListenersContainer
.getContainer(
3417 ::getCppuType( ( const uno::Reference
< embed::XTransactionListener
>*) NULL
) );
3420 ::cppu::OInterfaceIteratorHelper
pIterator( *pContainer
);
3421 while ( pIterator
.hasMoreElements( ) )
3423 OSL_ENSURE( nMessage
>= 1 && nMessage
<= 4, "Wrong internal notification code is used!\n" );
3427 case STOR_MESS_PRECOMMIT
:
3428 ( ( embed::XTransactionListener
* )pIterator
.next( ) )->preCommit( aSource
);
3430 case STOR_MESS_COMMITED
:
3431 ( ( embed::XTransactionListener
* )pIterator
.next( ) )->commited( aSource
);
3433 case STOR_MESS_PREREVERT
:
3434 ( ( embed::XTransactionListener
* )pIterator
.next( ) )->preRevert( aSource
);
3436 case STOR_MESS_REVERTED
:
3437 ( ( embed::XTransactionListener
* )pIterator
.next( ) )->reverted( aSource
);
3443 //-----------------------------------------------
3444 void SAL_CALL
OWriteStream::commit()
3445 throw ( io::IOException
,
3446 embed::StorageWrappedTargetException
,
3447 uno::RuntimeException
)
3449 RTL_LOGFILE_CONTEXT( aLog
, "package (mv76033) OWriteStream::commit" );
3453 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3454 throw lang::DisposedException();
3457 if ( !m_bTransacted
)
3458 throw uno::RuntimeException();
3461 BroadcastTransaction( STOR_MESS_PRECOMMIT
);
3463 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3467 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3468 throw lang::DisposedException();
3473 // when the storage is commited the parent is modified
3474 ModifyParentUnlockMutex_Impl( aGuard
);
3476 catch( io::IOException
& aIOException
)
3478 m_pImpl
->AddLog( aIOException
.Message
);
3479 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
3482 catch( embed::StorageWrappedTargetException
& aStorageWrappedTargetException
)
3484 m_pImpl
->AddLog( aStorageWrappedTargetException
.Message
);
3485 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
3488 catch( uno::RuntimeException
& aRuntimeException
)
3490 m_pImpl
->AddLog( aRuntimeException
.Message
);
3491 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
3494 catch( uno::Exception
& aException
)
3496 m_pImpl
->AddLog( aException
.Message
);
3497 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
3499 uno::Any
aCaught( ::cppu::getCaughtException() );
3500 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Problems on commit!" ),
3501 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >( this ) ),
3505 BroadcastTransaction( STOR_MESS_COMMITED
);
3508 //-----------------------------------------------
3509 void SAL_CALL
OWriteStream::revert()
3510 throw ( io::IOException
,
3511 embed::StorageWrappedTargetException
,
3512 uno::RuntimeException
)
3514 RTL_LOGFILE_CONTEXT( aLog
, "package (mv76033) OWriteStream::revert" );
3516 // the method removes all the changes done after last commit
3520 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3521 throw lang::DisposedException();
3524 if ( !m_bTransacted
)
3525 throw uno::RuntimeException();
3527 BroadcastTransaction( STOR_MESS_PREREVERT
);
3529 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3533 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3534 throw lang::DisposedException();
3540 catch( io::IOException
& aIOException
)
3542 m_pImpl
->AddLog( aIOException
.Message
);
3543 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
3546 catch( embed::StorageWrappedTargetException
& aStorageWrappedTargetException
)
3548 m_pImpl
->AddLog( aStorageWrappedTargetException
.Message
);
3549 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
3552 catch( uno::RuntimeException
& aRuntimeException
)
3554 m_pImpl
->AddLog( aRuntimeException
.Message
);
3555 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
3558 catch( uno::Exception
& aException
)
3560 m_pImpl
->AddLog( aException
.Message
);
3561 m_pImpl
->AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Rethrow" ) ) );
3563 uno::Any
aCaught( ::cppu::getCaughtException() );
3564 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Problems on revert!" ),
3565 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >( this ) ),
3571 BroadcastTransaction( STOR_MESS_REVERTED
);
3574 //____________________________________________________________________________________________________
3575 // XTransactionBroadcaster
3576 //____________________________________________________________________________________________________
3578 //-----------------------------------------------
3579 void SAL_CALL
OWriteStream::addTransactionListener( const uno::Reference
< embed::XTransactionListener
>& aListener
)
3580 throw ( uno::RuntimeException
)
3582 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3586 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3587 throw lang::DisposedException();
3590 if ( !m_bTransacted
)
3591 throw uno::RuntimeException();
3593 m_pData
->m_aListenersContainer
.addInterface( ::getCppuType((const uno::Reference
< embed::XTransactionListener
>*)0),
3597 //-----------------------------------------------
3598 void SAL_CALL
OWriteStream::removeTransactionListener( const uno::Reference
< embed::XTransactionListener
>& aListener
)
3599 throw ( uno::RuntimeException
)
3601 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3605 ::package::StaticAddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
"Disposed!" ) ) );
3606 throw lang::DisposedException();
3609 if ( !m_bTransacted
)
3610 throw uno::RuntimeException();
3612 m_pData
->m_aListenersContainer
.removeInterface( ::getCppuType((const uno::Reference
< embed::XTransactionListener
>*)0),