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 #ifndef _COMPHELPER_PROCESSFACTORY_HXX
47 #include <comphelper/processfactory.hxx>
50 #include <comphelper/storagehelper.hxx>
51 #include <comphelper/ofopxmlhelper.hxx>
53 #include "owriteablestream.hxx"
54 #include "oseekinstream.hxx"
55 #include "mutexholder.hxx"
56 #include "xstorage.hxx"
58 #include <rtl/digest.h>
59 #include <rtl/logfile.hxx>
62 using namespace ::com::sun::star
;
64 //-----------------------------------------------
65 void SetEncryptionKeyProperty_Impl( const uno::Reference
< beans::XPropertySet
>& xPropertySet
,
66 const uno::Sequence
< sal_Int8
>& aKey
)
68 OSL_ENSURE( xPropertySet
.is(), "No property set is provided!\n" );
69 if ( !xPropertySet
.is() )
70 throw uno::RuntimeException();
72 ::rtl::OUString aString_EncryptionKey
= ::rtl::OUString::createFromAscii( "EncryptionKey" );
74 xPropertySet
->setPropertyValue( aString_EncryptionKey
, uno::makeAny( aKey
) );
76 catch ( uno::Exception
& )
78 OSL_ENSURE( sal_False
, "Can't write encryption related properties!\n" );
79 throw io::IOException(); // TODO
83 //-----------------------------------------------
84 uno::Any
GetEncryptionKeyProperty_Impl( const uno::Reference
< beans::XPropertySet
>& xPropertySet
)
86 OSL_ENSURE( xPropertySet
.is(), "No property set is provided!\n" );
87 if ( !xPropertySet
.is() )
88 throw uno::RuntimeException();
90 ::rtl::OUString aString_EncryptionKey
= ::rtl::OUString::createFromAscii( "EncryptionKey" );
92 return xPropertySet
->getPropertyValue( aString_EncryptionKey
);
94 catch ( uno::Exception
& )
96 OSL_ENSURE( sal_False
, "Can't get encryption related properties!\n" );
97 throw io::IOException(); // TODO
101 //-----------------------------------------------
102 sal_Bool
SequencesEqual( uno::Sequence
< sal_Int8
> aSequence1
, uno::Sequence
< sal_Int8
> aSequence2
)
104 if ( aSequence1
.getLength() != aSequence2
.getLength() )
107 for ( sal_Int32 nInd
= 0; nInd
< aSequence1
.getLength(); nInd
++ )
108 if ( aSequence1
[nInd
] != aSequence2
[nInd
] )
114 //-----------------------------------------------
115 sal_Bool
KillFile( const ::rtl::OUString
& aURL
, const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
117 if ( !xFactory
.is() )
120 sal_Bool bRet
= sal_False
;
124 uno::Reference
< ucb::XSimpleFileAccess
> xAccess(
125 xFactory
->createInstance (
126 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
131 xAccess
->kill( aURL
);
135 catch( uno::Exception
& )
142 const sal_Int32 n_ConstBufferSize
= 32000;
144 //-----------------------------------------------
146 ::rtl::OUString
GetNewTempFileURL( const uno::Reference
< lang::XMultiServiceFactory
> xFactory
)
148 ::rtl::OUString aTempURL
;
150 uno::Reference
< beans::XPropertySet
> xTempFile(
151 xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
154 if ( !xTempFile
.is() )
155 throw uno::RuntimeException(); // TODO
158 xTempFile
->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ), uno::makeAny( sal_False
) );
159 uno::Any aUrl
= xTempFile
->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
162 catch ( uno::Exception
& )
166 if ( !aTempURL
.getLength() )
167 throw uno::RuntimeException(); // TODO: can not create tempfile
172 uno::Sequence
< sal_Int8
> MakeKeyFromPass( ::rtl::OUString aPass
, sal_Bool bUseUTF
)
174 // MS_1252 encoding was used for SO60 document format password encoding,
175 // this encoding supports only a minor subset of nonascii characters,
176 // but for compatibility reasons it has to be used for old document formats
178 ::rtl::OString aByteStrPass
;
180 aByteStrPass
= ::rtl::OUStringToOString( aPass
, RTL_TEXTENCODING_UTF8
);
182 aByteStrPass
= ::rtl::OUStringToOString( aPass
, RTL_TEXTENCODING_MS_1252
);
184 sal_uInt8 pBuffer
[RTL_DIGEST_LENGTH_SHA1
];
185 rtlDigestError nError
= rtl_digest_SHA1( aByteStrPass
.getStr(),
186 aByteStrPass
.getLength(),
188 RTL_DIGEST_LENGTH_SHA1
);
190 if ( nError
!= rtl_Digest_E_None
)
191 throw uno::RuntimeException();
193 return uno::Sequence
< sal_Int8
>( (sal_Int8
*)pBuffer
, RTL_DIGEST_LENGTH_SHA1
);
197 // ================================================================
199 //-----------------------------------------------
200 OWriteStream_Impl::OWriteStream_Impl( OStorage_Impl
* pParent
,
201 const uno::Reference
< packages::XDataSinkEncrSupport
>& xPackageStream
,
202 const uno::Reference
< lang::XSingleServiceFactory
>& xPackage
,
203 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
,
204 sal_Bool bForceEncrypted
,
205 sal_Int16 nStorageType
,
206 const uno::Reference
< io::XInputStream
>& xRelInfoStream
)
207 : m_pAntiImpl( NULL
)
208 , m_bHasDataToFlush( sal_False
)
209 , m_bFlushed( sal_False
)
210 , m_xPackageStream( xPackageStream
)
211 , m_xFactory( xFactory
)
212 , m_pParent( pParent
)
213 , m_bForceEncrypted( bForceEncrypted
)
214 , m_bUseCommonPass( !bForceEncrypted
&& nStorageType
== PACKAGE_STORAGE
)
215 , m_bHasCachedPassword( sal_False
)
216 , m_xPackage( xPackage
)
217 , m_bHasInsertedStreamOptimization( sal_False
)
218 , m_nStorageType( nStorageType
)
219 , m_xOrigRelInfoStream( xRelInfoStream
)
220 , m_bOrigRelInfoBroken( sal_False
)
221 , m_nRelInfoStatus( RELINFO_NO_INIT
)
224 OSL_ENSURE( xPackageStream
.is(), "No package stream is provided!\n" );
225 OSL_ENSURE( xPackage
.is(), "No package component is provided!\n" );
226 OSL_ENSURE( m_xFactory
.is(), "No package stream is provided!\n" );
227 OSL_ENSURE( pParent
, "No parent storage is provided!\n" );
228 OSL_ENSURE( m_nStorageType
== OFOPXML_STORAGE
|| !m_xOrigRelInfoStream
.is(), "The Relations info makes sence only for OFOPXML format!\n" );
231 //-----------------------------------------------
232 OWriteStream_Impl::~OWriteStream_Impl()
236 if ( m_aTempURL
.getLength() )
238 KillFile( m_aTempURL
, GetServiceFactory() );
239 m_aTempURL
= ::rtl::OUString();
243 //-----------------------------------------------
244 void OWriteStream_Impl::InsertIntoPackageFolder( const ::rtl::OUString
& aName
,
245 const uno::Reference
< container::XNameContainer
>& xParentPackageFolder
)
247 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() );
249 OSL_ENSURE( m_bFlushed
, "This method must not be called for nonflushed streams!\n" );
252 OSL_ENSURE( m_xPackageStream
.is(), "An inserted stream is incomplete!\n" );
253 uno::Reference
< lang::XUnoTunnel
> xTunnel( m_xPackageStream
, uno::UNO_QUERY
);
255 throw uno::RuntimeException(); // TODO
257 xParentPackageFolder
->insertByName( aName
, uno::makeAny( xTunnel
) );
259 m_bFlushed
= sal_False
;
260 m_bHasInsertedStreamOptimization
= sal_False
;
263 //-----------------------------------------------
264 sal_Bool
OWriteStream_Impl::IsEncrypted()
266 if ( m_nStorageType
!= PACKAGE_STORAGE
)
269 if ( m_bForceEncrypted
|| m_bHasCachedPassword
)
272 if ( m_aTempURL
.getLength() )
275 GetStreamProperties();
277 // the following value can not be cached since it can change after root commit
278 sal_Bool bWasEncr
= sal_False
;
279 uno::Reference
< beans::XPropertySet
> xPropSet( m_xPackageStream
, uno::UNO_QUERY
);
282 uno::Any aValue
= xPropSet
->getPropertyValue( ::rtl::OUString::createFromAscii( "WasEncrypted" ) );
283 if ( !( aValue
>>= bWasEncr
) )
285 OSL_ENSURE( sal_False
, "The property WasEncrypted has wrong type!\n" );
289 sal_Bool bToBeEncr
= sal_False
;
290 for ( sal_Int32 nInd
= 0; nInd
< m_aProps
.getLength(); nInd
++ )
292 if ( m_aProps
[nInd
].Name
.equalsAscii( "Encrypted" ) )
294 if ( !( m_aProps
[nInd
].Value
>>= bToBeEncr
) )
296 OSL_ENSURE( sal_False
, "The property has wrong type!\n" );
301 // since a new key set to the package stream it should not be removed except the case when
302 // the stream becomes nonencrypted
303 uno::Sequence
< sal_Int8
> aKey
;
305 GetEncryptionKeyProperty_Impl( xPropSet
) >>= aKey
;
307 // If the properties must be investigated the stream is either
308 // was never changed or was changed, the parent was commited
309 // and the stream was closed.
310 // That means that if it is intended to use common storage key
311 // it is already has no encryption but is marked to be stored
312 // encrypted and the key is empty.
313 if ( !bWasEncr
&& bToBeEncr
&& !aKey
.getLength() )
315 // the stream is intended to use common storage password
316 m_bUseCommonPass
= sal_True
;
323 //-----------------------------------------------
324 void OWriteStream_Impl::SetDecrypted()
326 OSL_ENSURE( m_nStorageType
== PACKAGE_STORAGE
, "The encryption is supported only for package storages!\n" );
327 if ( m_nStorageType
!= PACKAGE_STORAGE
)
328 throw uno::RuntimeException();
330 GetStreamProperties();
332 // let the stream be modified
334 m_bHasDataToFlush
= sal_True
;
337 m_bForceEncrypted
= sal_False
;
338 m_bHasCachedPassword
= sal_False
;
339 m_aPass
= ::rtl::OUString();
341 for ( sal_Int32 nInd
= 0; nInd
< m_aProps
.getLength(); nInd
++ )
343 if ( m_aProps
[nInd
].Name
.equalsAscii( "Encrypted" ) )
344 m_aProps
[nInd
].Value
<<= sal_False
;
348 //-----------------------------------------------
349 void OWriteStream_Impl::SetEncryptedWithPass( const ::rtl::OUString
& aPass
)
351 OSL_ENSURE( m_nStorageType
== PACKAGE_STORAGE
, "The encryption is supported only for package storages!\n" );
352 if ( m_nStorageType
!= PACKAGE_STORAGE
)
353 throw uno::RuntimeException();
355 GetStreamProperties();
357 // let the stream be modified
359 m_bHasDataToFlush
= sal_True
;
361 // introduce encryption info
362 for ( sal_Int32 nInd
= 0; nInd
< m_aProps
.getLength(); nInd
++ )
364 if ( m_aProps
[nInd
].Name
.equalsAscii( "Encrypted" ) )
365 m_aProps
[nInd
].Value
<<= sal_True
;
368 m_bUseCommonPass
= sal_False
; // very important to set it to false
370 m_bHasCachedPassword
= sal_True
;
374 //-----------------------------------------------
375 void OWriteStream_Impl::DisposeWrappers()
377 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() );
381 m_pAntiImpl
->dispose();
383 catch ( uno::RuntimeException
& )
389 if ( !m_aInputStreamsList
.empty() )
391 for ( InputStreamsList_Impl::iterator pStreamIter
= m_aInputStreamsList
.begin();
392 pStreamIter
!= m_aInputStreamsList
.end(); pStreamIter
++ )
394 if ( (*pStreamIter
) )
396 (*pStreamIter
)->InternalDispose();
397 (*pStreamIter
) = NULL
;
401 m_aInputStreamsList
.clear();
405 //-----------------------------------------------
406 uno::Reference
< lang::XMultiServiceFactory
> OWriteStream_Impl::GetServiceFactory()
408 if ( m_xFactory
.is() )
411 return ::comphelper::getProcessServiceFactory();
414 //-----------------------------------------------
415 ::rtl::OUString
OWriteStream_Impl::GetFilledTempFile()
417 if ( !m_aTempURL
.getLength() )
419 m_aTempURL
= GetNewTempFileURL( GetServiceFactory() );
424 uno::Reference
< ucb::XSimpleFileAccess
> xTempAccess(
425 GetServiceFactory()->createInstance (
426 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
429 if ( !xTempAccess
.is() )
430 throw uno::RuntimeException(); // TODO:
433 // in case of new inserted package stream it is possible that input stream still was not set
434 uno::Reference
< io::XInputStream
> xOrigStream
= m_xPackageStream
->getDataStream();
435 if ( xOrigStream
.is() )
437 uno::Reference
< io::XOutputStream
> xTempOutStream
= xTempAccess
->openFileWrite( m_aTempURL
);
438 if ( xTempOutStream
.is() )
440 // copy stream contents to the file
441 ::comphelper::OStorageHelper::CopyInputToOutput( xOrigStream
, xTempOutStream
);
442 xTempOutStream
->closeOutput();
443 xTempOutStream
= uno::Reference
< io::XOutputStream
>();
446 throw io::IOException(); // TODO:
450 catch( packages::WrongPasswordException
& )
452 KillFile( m_aTempURL
, GetServiceFactory() );
453 m_aTempURL
= ::rtl::OUString();
457 catch( uno::Exception
& )
459 KillFile( m_aTempURL
, GetServiceFactory() );
460 m_aTempURL
= ::rtl::OUString();
467 //-----------------------------------------------
468 uno::Reference
< io::XStream
> OWriteStream_Impl::GetTempFileAsStream()
470 uno::Reference
< io::XStream
> xTempStream
;
472 if ( !m_aTempURL
.getLength() )
473 m_aTempURL
= GetFilledTempFile();
475 uno::Reference
< ucb::XSimpleFileAccess
> xTempAccess(
476 GetServiceFactory()->createInstance (
477 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
480 if ( !xTempAccess
.is() )
481 throw uno::RuntimeException(); // TODO:
485 xTempStream
= xTempAccess
->openFileReadWrite( m_aTempURL
);
487 catch( uno::Exception
& )
491 // the method must always return a stream
492 // in case the stream can not be open
493 // an exception should be thrown
494 if ( !xTempStream
.is() )
495 throw io::IOException(); //TODO:
500 //-----------------------------------------------
501 uno::Reference
< io::XInputStream
> OWriteStream_Impl::GetTempFileAsInputStream()
503 uno::Reference
< io::XInputStream
> xInputStream
;
505 if ( !m_aTempURL
.getLength() )
506 m_aTempURL
= GetFilledTempFile();
508 uno::Reference
< ucb::XSimpleFileAccess
> xTempAccess(
509 GetServiceFactory()->createInstance (
510 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
513 if ( !xTempAccess
.is() )
514 throw uno::RuntimeException(); // TODO:
518 xInputStream
= xTempAccess
->openFileRead( m_aTempURL
);
520 catch( uno::Exception
& )
524 // the method must always return a stream
525 // in case the stream can not be open
526 // an exception should be thrown
527 if ( !xInputStream
.is() )
528 throw io::IOException(); // TODO:
533 //-----------------------------------------------
534 void OWriteStream_Impl::CopyTempFileToOutput( uno::Reference
< io::XOutputStream
> xOutStream
)
536 OSL_ENSURE( xOutStream
.is(), "The stream must be specified!\n" );
537 OSL_ENSURE( m_aTempURL
.getLength(), "The temporary must exist!\n" );
539 uno::Reference
< ucb::XSimpleFileAccess
> xTempAccess(
540 GetServiceFactory()->createInstance (
541 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
544 if ( !xTempAccess
.is() )
545 throw uno::RuntimeException(); // TODO:
547 uno::Reference
< io::XInputStream
> xTempInStream
;
550 xTempInStream
= xTempAccess
->openFileRead( m_aTempURL
);
552 catch( uno::Exception
& )
556 if ( !xTempInStream
.is() )
557 throw io::IOException(); //TODO:
559 ::comphelper::OStorageHelper::CopyInputToOutput( xTempInStream
, xOutStream
);
562 // =================================================================================================
564 //-----------------------------------------------
565 void OWriteStream_Impl::InsertStreamDirectly( const uno::Reference
< io::XInputStream
>& xInStream
,
566 const uno::Sequence
< beans::PropertyValue
>& aProps
)
568 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
570 // this call can be made only during parent storage commit
571 // the parent storage is responsible for the correct handling
572 // of deleted and renamed contents
574 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
576 if ( m_bHasDataToFlush
)
577 throw io::IOException();
579 OSL_ENSURE( !m_aTempURL
.getLength(), "The temporary must not exist!\n" );
581 // use new file as current persistent representation
582 // the new file will be removed after it's stream is closed
583 m_xPackageStream
->setDataStream( xInStream
);
585 // copy properties to the package stream
586 uno::Reference
< beans::XPropertySet
> xPropertySet( m_xPackageStream
, uno::UNO_QUERY
);
587 if ( !xPropertySet
.is() )
588 throw uno::RuntimeException();
590 // The storage-package communication has a problem
591 // the storage caches properties, thus if the package changes one of them itself
592 // the storage does not know about it
594 // Depending from MediaType value the package can change the compressed property itself
595 // Thus if Compressed property is provided it must be set as the latest one
596 sal_Bool bCompressedIsSet
= sal_False
;
597 sal_Bool bCompressed
= sal_False
;
598 ::rtl::OUString
aComprPropName( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) );
599 ::rtl::OUString
aMedTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
600 for ( sal_Int32 nInd
= 0; nInd
< aProps
.getLength(); nInd
++ )
602 if ( aProps
[nInd
].Name
.equals( aComprPropName
) )
604 bCompressedIsSet
= sal_True
;
605 aProps
[nInd
].Value
>>= bCompressed
;
607 else if ( ( m_nStorageType
== OFOPXML_STORAGE
|| m_nStorageType
== PACKAGE_STORAGE
)
608 && aProps
[nInd
].Name
.equals( aMedTypePropName
) )
610 xPropertySet
->setPropertyValue( aProps
[nInd
].Name
, aProps
[nInd
].Value
);
612 else if ( m_nStorageType
== PACKAGE_STORAGE
&& aProps
[nInd
].Name
.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
613 aProps
[nInd
].Value
>>= m_bUseCommonPass
;
615 throw lang::IllegalArgumentException();
617 // if there are cached properties update them
618 if ( aProps
[nInd
].Name
.equals( aMedTypePropName
) || aProps
[nInd
].Name
.equals( aComprPropName
) )
619 for ( sal_Int32 nMemInd
= 0; nMemInd
< m_aProps
.getLength(); nMemInd
++ )
621 if ( aProps
[nInd
].Name
.equals( m_aProps
[nMemInd
].Name
) )
622 m_aProps
[nMemInd
].Value
= aProps
[nInd
].Value
;
626 if ( bCompressedIsSet
)
627 xPropertySet
->setPropertyValue( aComprPropName
, uno::makeAny( (sal_Bool
)bCompressed
) );
629 if ( m_bUseCommonPass
)
631 if ( m_nStorageType
!= PACKAGE_STORAGE
)
632 throw uno::RuntimeException();
634 // set to be encrypted but do not use encryption key
635 xPropertySet
->setPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ),
636 uno::makeAny( uno::Sequence
< sal_Int8
>() ) );
637 xPropertySet
->setPropertyValue( ::rtl::OUString::createFromAscii( "Encrypted" ),
638 uno::makeAny( sal_True
) );
641 // the stream should be free soon, after package is stored
642 m_bHasDataToFlush
= sal_False
;
643 m_bFlushed
= sal_True
; // will allow to use transaction on stream level if will need it
644 m_bHasInsertedStreamOptimization
= sal_True
;
647 //-----------------------------------------------
648 void OWriteStream_Impl::Commit()
650 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
652 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
654 if ( !m_bHasDataToFlush
)
657 uno::Reference
< packages::XDataSinkEncrSupport
> xNewPackageStream
;
659 OSL_ENSURE( m_bHasInsertedStreamOptimization
|| m_aTempURL
.getLength(), "The temporary must exist!\n" );
660 if ( m_aTempURL
.getLength() )
662 uno::Reference
< io::XOutputStream
> xTempOut(
663 GetServiceFactory()->createInstance (
664 ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
666 uno::Reference
< io::XInputStream
> xTempIn( xTempOut
, uno::UNO_QUERY
);
668 if ( !xTempOut
.is() || !xTempIn
.is() )
669 throw io::IOException();
671 // Copy temporary file to a new one
672 CopyTempFileToOutput( xTempOut
);
673 xTempOut
->closeOutput();
675 uno::Sequence
< uno::Any
> aSeq( 1 );
676 aSeq
[0] <<= sal_False
;
677 xNewPackageStream
= uno::Reference
< packages::XDataSinkEncrSupport
>(
678 m_xPackage
->createInstanceWithArguments( aSeq
),
680 if ( !xNewPackageStream
.is() )
681 throw uno::RuntimeException();
683 // use new file as current persistent representation
684 // the new file will be removed after it's stream is closed
685 xNewPackageStream
->setDataStream( xTempIn
);
687 else // if ( m_bHasInsertedStreamOptimization )
689 // if the optimization is used the stream can be accessed directly
690 xNewPackageStream
= m_xPackageStream
;
693 // copy properties to the package stream
694 uno::Reference
< beans::XPropertySet
> xPropertySet( xNewPackageStream
, uno::UNO_QUERY
);
695 if ( !xPropertySet
.is() )
696 throw uno::RuntimeException();
698 for ( sal_Int32 nInd
= 0; nInd
< m_aProps
.getLength(); nInd
++ )
700 if ( m_aProps
[nInd
].Name
.equalsAscii( "Size" ) )
702 if ( m_pAntiImpl
&& !m_bHasInsertedStreamOptimization
&& m_pAntiImpl
->m_xSeekable
.is() )
704 m_aProps
[nInd
].Value
<<= ((sal_Int32
)m_pAntiImpl
->m_xSeekable
->getLength());
705 xPropertySet
->setPropertyValue( m_aProps
[nInd
].Name
, m_aProps
[nInd
].Value
);
709 xPropertySet
->setPropertyValue( m_aProps
[nInd
].Name
, m_aProps
[nInd
].Value
);
712 if ( m_bUseCommonPass
)
714 if ( m_nStorageType
!= PACKAGE_STORAGE
)
715 throw uno::RuntimeException();
717 // set to be encrypted but do not use encryption key
718 xPropertySet
->setPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ),
719 uno::makeAny( uno::Sequence
< sal_Int8
>() ) );
720 xPropertySet
->setPropertyValue( ::rtl::OUString::createFromAscii( "Encrypted" ),
721 uno::makeAny( sal_True
) );
723 else if ( m_bHasCachedPassword
)
725 if ( m_nStorageType
!= PACKAGE_STORAGE
)
726 throw uno::RuntimeException();
728 xPropertySet
->setPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ),
729 uno::makeAny( MakeKeyFromPass( m_aPass
, sal_True
) ) );
732 // the stream should be free soon, after package is stored
733 m_xPackageStream
= xNewPackageStream
;
734 m_bHasDataToFlush
= sal_False
;
735 m_bFlushed
= sal_True
; // will allow to use transaction on stream level if will need it
738 //-----------------------------------------------
739 void OWriteStream_Impl::Revert()
741 // can be called only from parent storage
742 // means complete reload of the stream
744 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
746 if ( !m_bHasDataToFlush
)
747 return; // nothing to do
749 OSL_ENSURE( m_aTempURL
.getLength(), "The temporary must exist!\n" );
751 if ( m_aTempURL
.getLength() )
753 KillFile( m_aTempURL
, GetServiceFactory() );
754 m_aTempURL
= ::rtl::OUString();
757 m_aProps
.realloc( 0 );
759 m_bHasDataToFlush
= sal_False
;
761 m_bUseCommonPass
= sal_True
;
762 m_bHasCachedPassword
= sal_False
;
763 m_aPass
= ::rtl::OUString();
765 if ( m_nStorageType
== OFOPXML_STORAGE
)
767 // currently the relations storage is changed only on commit
768 m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
769 m_aNewRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
770 if ( m_xOrigRelInfoStream
.is() )
772 // the original stream is still here, that means that it was not parsed
773 m_aOrigRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
774 m_nRelInfoStatus
= RELINFO_NO_INIT
;
778 // the original stream was aready parsed
779 if ( !m_bOrigRelInfoBroken
)
780 m_nRelInfoStatus
= RELINFO_READ
;
782 m_nRelInfoStatus
= RELINFO_BROKEN
;
787 //-----------------------------------------------
788 uno::Sequence
< beans::PropertyValue
> OWriteStream_Impl::GetStreamProperties()
790 if ( !m_aProps
.getLength() )
791 m_aProps
= ReadPackageStreamProperties();
796 //-----------------------------------------------
797 uno::Sequence
< beans::PropertyValue
> OWriteStream_Impl::InsertOwnProps(
798 const uno::Sequence
< beans::PropertyValue
>& aProps
,
799 sal_Bool bUseCommonPass
)
801 uno::Sequence
< beans::PropertyValue
> aResult( aProps
);
802 sal_Int32 nLen
= aResult
.getLength();
804 if ( m_nStorageType
== PACKAGE_STORAGE
)
806 for ( sal_Int32 nInd
= 0; nInd
< nLen
; nInd
++ )
807 if ( aResult
[nInd
].Name
.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
809 aResult
[nInd
].Value
<<= bUseCommonPass
;
813 aResult
.realloc( ++nLen
);
814 aResult
[nLen
- 1].Name
= ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" );
815 aResult
[nLen
- 1].Value
<<= bUseCommonPass
;
817 else if ( m_nStorageType
== OFOPXML_STORAGE
)
819 ReadRelInfoIfNecessary();
822 if ( m_nRelInfoStatus
== RELINFO_READ
)
823 aValue
<<= m_aOrigRelInfo
;
824 else if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM_READ
|| m_nRelInfoStatus
== RELINFO_CHANGED
)
825 aValue
<<= m_aNewRelInfo
;
826 else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
827 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Wrong relinfo stream!" ) ),
828 uno::Reference
< uno::XInterface
>() );
830 for ( sal_Int32 nInd
= 0; nInd
< nLen
; nInd
++ )
831 if ( aResult
[nInd
].Name
.equalsAscii( "RelationsInfo" ) )
833 aResult
[nInd
].Value
= aValue
;
837 aResult
.realloc( ++nLen
);
838 aResult
[nLen
- 1].Name
= ::rtl::OUString::createFromAscii( "RelationsInfo" );
839 aResult
[nLen
- 1].Value
= aValue
;
845 //-----------------------------------------------
846 sal_Bool
OWriteStream_Impl::IsTransacted()
848 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
849 return ( m_pAntiImpl
&& m_pAntiImpl
->m_bTransacted
);
852 void OWriteStream_Impl::ReadRelInfoIfNecessary()
854 if ( m_nStorageType
!= OFOPXML_STORAGE
)
857 if ( m_nRelInfoStatus
== RELINFO_NO_INIT
)
861 // Init from original stream
862 if ( m_xOrigRelInfoStream
.is() )
863 m_aOrigRelInfo
= ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
864 m_xOrigRelInfoStream
,
865 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/*.rels" ) ),
868 // in case of success the stream must be thrown away, that means that the OrigRelInfo is initialized
869 // the reason for this is that the original stream might not be seekable ( at the same time the new
870 // provided stream must be seekable ), so it must be read only once
871 m_xOrigRelInfoStream
= uno::Reference
< io::XInputStream
>();
872 m_nRelInfoStatus
= RELINFO_READ
;
874 catch( uno::Exception
& )
876 m_nRelInfoStatus
= RELINFO_BROKEN
;
877 m_bOrigRelInfoBroken
= sal_True
;
880 else if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
882 // Init from the new stream
885 if ( m_xNewRelInfoStream
.is() )
886 m_aNewRelInfo
= ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
888 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/*.rels" ) ),
891 m_nRelInfoStatus
= RELINFO_CHANGED_STREAM_READ
;
893 catch( uno::Exception
)
895 m_nRelInfoStatus
= RELINFO_CHANGED_BROKEN
;
900 //-----------------------------------------------
901 uno::Sequence
< beans::PropertyValue
> OWriteStream_Impl::ReadPackageStreamProperties()
903 sal_Int32 nPropNum
= 0;
904 if ( m_nStorageType
== ZIP_STORAGE
)
906 else if ( m_nStorageType
== OFOPXML_STORAGE
)
908 else if ( m_nStorageType
== PACKAGE_STORAGE
)
910 uno::Sequence
< beans::PropertyValue
> aResult( nPropNum
);
912 // The "Compressed" property must be set after "MediaType" property,
913 // since the setting of the last one can change the value of the first one
915 if ( m_nStorageType
== OFOPXML_STORAGE
|| m_nStorageType
== PACKAGE_STORAGE
)
917 aResult
[0].Name
= ::rtl::OUString::createFromAscii("MediaType");
918 aResult
[1].Name
= ::rtl::OUString::createFromAscii("Compressed");
919 aResult
[2].Name
= ::rtl::OUString::createFromAscii("Size");
921 if ( m_nStorageType
== PACKAGE_STORAGE
)
922 aResult
[3].Name
= ::rtl::OUString::createFromAscii("Encrypted");
926 aResult
[0].Name
= ::rtl::OUString::createFromAscii("Compressed");
927 aResult
[1].Name
= ::rtl::OUString::createFromAscii("Size");
931 // TODO: may be also raw stream should be marked
933 uno::Reference
< beans::XPropertySet
> xPropSet( m_xPackageStream
, uno::UNO_QUERY
);
936 for ( sal_Int32 nInd
= 0; nInd
< aResult
.getLength(); nInd
++ )
939 aResult
[nInd
].Value
= xPropSet
->getPropertyValue( aResult
[nInd
].Name
);
941 catch( uno::Exception
& )
943 OSL_ENSURE( sal_False
, "A property can't be retrieved!\n" );
949 OSL_ENSURE( sal_False
, "Can not get properties from a package stream!\n" );
950 throw uno::RuntimeException();
956 //-----------------------------------------------
957 void OWriteStream_Impl::CopyInternallyTo_Impl( const uno::Reference
< io::XStream
>& xDestStream
,
958 const ::rtl::OUString
& aPass
)
960 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
962 OSL_ENSURE( !m_bUseCommonPass
, "The stream can not be encrypted!" );
964 if ( m_nStorageType
!= PACKAGE_STORAGE
)
965 throw packages::NoEncryptionException();
969 m_pAntiImpl
->CopyToStreamInternally_Impl( xDestStream
);
973 uno::Reference
< io::XStream
> xOwnStream
= GetStream( embed::ElementModes::READ
, aPass
, sal_False
);
974 if ( !xOwnStream
.is() )
975 throw io::IOException(); // TODO
977 OStorage_Impl::completeStorageStreamCopy_Impl( xOwnStream
, xDestStream
, m_nStorageType
, GetAllRelationshipsIfAny() );
980 uno::Reference
< embed::XEncryptionProtectedSource
> xEncr( xDestStream
, uno::UNO_QUERY
);
982 xEncr
->setEncryptionPassword( aPass
);
985 //-----------------------------------------------
986 uno::Sequence
< uno::Sequence
< beans::StringPair
> > OWriteStream_Impl::GetAllRelationshipsIfAny()
988 if ( m_nStorageType
!= OFOPXML_STORAGE
)
989 return uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
991 ReadRelInfoIfNecessary();
993 if ( m_nRelInfoStatus
== RELINFO_READ
)
994 return m_aOrigRelInfo
;
995 else if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM_READ
|| m_nRelInfoStatus
== RELINFO_CHANGED
)
996 return m_aNewRelInfo
;
997 else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
998 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Wrong relinfo stream!" ) ),
999 uno::Reference
< uno::XInterface
>() );
1002 //-----------------------------------------------
1003 void OWriteStream_Impl::CopyInternallyTo_Impl( const uno::Reference
< io::XStream
>& xDestStream
)
1005 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1009 m_pAntiImpl
->CopyToStreamInternally_Impl( xDestStream
);
1013 uno::Reference
< io::XStream
> xOwnStream
= GetStream( embed::ElementModes::READ
, sal_False
);
1014 if ( !xOwnStream
.is() )
1015 throw io::IOException(); // TODO
1017 OStorage_Impl::completeStorageStreamCopy_Impl( xOwnStream
, xDestStream
, m_nStorageType
, GetAllRelationshipsIfAny() );
1021 //-----------------------------------------------
1022 uno::Reference
< io::XStream
> OWriteStream_Impl::GetStream( sal_Int32 nStreamMode
, const ::rtl::OUString
& aPass
, sal_Bool bHierarchyAccess
)
1024 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1026 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
1029 throw io::IOException(); // TODO:
1031 if ( !IsEncrypted() )
1032 throw packages::NoEncryptionException();
1034 uno::Reference
< io::XStream
> xResultStream
;
1036 uno::Reference
< beans::XPropertySet
> xPropertySet( m_xPackageStream
, uno::UNO_QUERY
);
1037 if ( !xPropertySet
.is() )
1038 throw uno::RuntimeException();
1040 if ( m_bHasCachedPassword
)
1042 if ( !m_aPass
.equals( aPass
) )
1043 throw packages::WrongPasswordException();
1045 // the correct key must be set already
1046 xResultStream
= GetStream_Impl( nStreamMode
, bHierarchyAccess
);
1050 SetEncryptionKeyProperty_Impl( xPropertySet
, MakeKeyFromPass( aPass
, sal_True
) );
1053 xResultStream
= GetStream_Impl( nStreamMode
, bHierarchyAccess
);
1055 m_bUseCommonPass
= sal_False
; // very important to set it to false
1056 m_bHasCachedPassword
= sal_True
;
1059 catch( packages::WrongPasswordException
& )
1061 // retry with different encoding
1062 SetEncryptionKeyProperty_Impl( xPropertySet
, MakeKeyFromPass( aPass
, sal_False
) );
1064 // the stream must be cashed to be resaved
1065 xResultStream
= GetStream_Impl( nStreamMode
| embed::ElementModes::SEEKABLE
, bHierarchyAccess
);
1067 m_bUseCommonPass
= sal_False
; // very important to set it to false
1068 m_bHasCachedPassword
= sal_True
;
1071 // the stream must be resaved with new password encryption
1072 if ( nStreamMode
& embed::ElementModes::WRITE
)
1074 GetFilledTempFile();
1075 m_bHasDataToFlush
= sal_True
;
1077 // TODO/LATER: should the notification be done?
1079 m_pParent
->m_bIsModified
= sal_True
;
1082 catch( packages::WrongPasswordException
& )
1084 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1087 catch ( uno::Exception
& )
1089 OSL_ENSURE( sal_False
, "Can't write encryption related properties!\n" );
1090 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1091 throw io::IOException(); // TODO:
1094 catch( uno::Exception
& )
1096 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1103 OSL_ENSURE( xResultStream
.is(), "In case stream can not be retrieved an exception must be thrown!\n" );
1105 return xResultStream
;
1108 //-----------------------------------------------
1109 uno::Reference
< io::XStream
> OWriteStream_Impl::GetStream( sal_Int32 nStreamMode
, sal_Bool bHierarchyAccess
)
1111 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1113 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
1116 throw io::IOException(); // TODO:
1118 uno::Reference
< io::XStream
> xResultStream
;
1120 if ( IsEncrypted() )
1122 ::rtl::OUString aGlobalPass
;
1125 aGlobalPass
= GetCommonRootPass();
1127 catch( packages::NoEncryptionException
& )
1129 throw packages::WrongPasswordException();
1132 xResultStream
= GetStream( nStreamMode
, aGlobalPass
, bHierarchyAccess
);
1135 xResultStream
= GetStream_Impl( nStreamMode
, bHierarchyAccess
);
1137 return xResultStream
;
1140 //-----------------------------------------------
1141 uno::Reference
< io::XStream
> OWriteStream_Impl::GetStream_Impl( sal_Int32 nStreamMode
, sal_Bool bHierarchyAccess
)
1143 // private method, no mutex is used
1144 GetStreamProperties();
1146 // TODO/LATER: this info might be read later, on demand in future
1147 ReadRelInfoIfNecessary();
1149 if ( ( nStreamMode
& embed::ElementModes::READWRITE
) == embed::ElementModes::READ
)
1151 uno::Reference
< io::XInputStream
> xInStream
;
1152 if ( m_aTempURL
.getLength() )
1153 xInStream
= GetTempFileAsInputStream(); //TODO:
1155 xInStream
= m_xPackageStream
->getDataStream();
1157 // The stream does not exist in the storage
1158 if ( !xInStream
.is() )
1159 throw io::IOException();
1161 OInputCompStream
* pStream
= new OInputCompStream( *this, xInStream
, InsertOwnProps( m_aProps
, m_bUseCommonPass
), m_nStorageType
);
1162 uno::Reference
< io::XStream
> xCompStream(
1163 static_cast< ::cppu::OWeakObject
* >( pStream
),
1165 OSL_ENSURE( xCompStream
.is(),
1166 "OInputCompStream MUST provide XStream interfaces!\n" );
1168 m_aInputStreamsList
.push_back( pStream
);
1171 else if ( ( nStreamMode
& embed::ElementModes::READWRITE
) == embed::ElementModes::SEEKABLEREAD
)
1173 if ( !m_aTempURL
.getLength() && !( m_xPackageStream
->getDataStream().is() ) )
1175 // The stream does not exist in the storage
1176 throw io::IOException();
1179 uno::Reference
< io::XInputStream
> xInStream
;
1181 xInStream
= GetTempFileAsInputStream(); //TODO:
1183 if ( !xInStream
.is() )
1184 throw io::IOException();
1186 OInputSeekStream
* pStream
= new OInputSeekStream( *this, xInStream
, InsertOwnProps( m_aProps
, m_bUseCommonPass
), m_nStorageType
);
1187 uno::Reference
< io::XStream
> xSeekStream(
1188 static_cast< ::cppu::OWeakObject
* >( pStream
),
1190 OSL_ENSURE( xSeekStream
.is(),
1191 "OInputSeekStream MUST provide XStream interfaces!\n" );
1193 m_aInputStreamsList
.push_back( pStream
);
1196 else if ( ( nStreamMode
& embed::ElementModes::WRITE
) == embed::ElementModes::WRITE
)
1198 if ( !m_aInputStreamsList
.empty() )
1199 throw io::IOException(); // TODO:
1201 uno::Reference
< io::XStream
> xStream
;
1202 if ( ( nStreamMode
& embed::ElementModes::TRUNCATE
) == embed::ElementModes::TRUNCATE
)
1204 if ( m_aTempURL
.getLength() )
1205 KillFile( m_aTempURL
, GetServiceFactory() );
1207 // open new empty temp file
1208 m_aTempURL
= GetNewTempFileURL( GetServiceFactory() );
1210 m_bHasDataToFlush
= sal_True
;
1212 // this call is triggered by the parent and it will recognize the change of the state
1214 m_pParent
->m_bIsModified
= sal_True
;
1216 xStream
= GetTempFileAsStream();
1218 else if ( !m_bHasInsertedStreamOptimization
)
1220 if ( !m_aTempURL
.getLength() && !( m_xPackageStream
->getDataStream().is() ) )
1222 // The stream does not exist in the storage
1223 m_bHasDataToFlush
= sal_True
;
1225 // this call is triggered by the parent and it will recognize the change of the state
1227 m_pParent
->m_bIsModified
= sal_True
;
1228 xStream
= GetTempFileAsStream();
1231 // if the stream exists the temporary file is created on demand
1232 // xStream = GetTempFileAsStream();
1235 if ( !xStream
.is() )
1236 m_pAntiImpl
= new OWriteStream( this, bHierarchyAccess
);
1238 m_pAntiImpl
= new OWriteStream( this, xStream
, bHierarchyAccess
);
1240 uno::Reference
< io::XStream
> xWriteStream
=
1241 uno::Reference
< io::XStream
>( static_cast< ::cppu::OWeakObject
* >( m_pAntiImpl
),
1244 OSL_ENSURE( xWriteStream
.is(), "OWriteStream MUST implement XStream && XComponent interfaces!\n" );
1246 return xWriteStream
;
1249 throw lang::IllegalArgumentException(); // TODO
1252 //-----------------------------------------------
1253 uno::Reference
< io::XInputStream
> OWriteStream_Impl::GetPlainRawInStream()
1255 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1257 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
1259 // this method is used only internally, this stream object should not go outside of this implementation
1260 // if ( m_pAntiImpl )
1261 // throw io::IOException(); // TODO:
1263 return m_xPackageStream
->getPlainRawStream();
1266 //-----------------------------------------------
1267 uno::Reference
< io::XInputStream
> OWriteStream_Impl::GetRawInStream()
1269 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1271 OSL_ENSURE( m_xPackageStream
.is(), "No package stream is set!\n" );
1274 throw io::IOException(); // TODO:
1276 OSL_ENSURE( IsEncrypted(), "Impossible to get raw representation for nonencrypted stream!\n" );
1277 if ( !IsEncrypted() )
1278 throw packages::NoEncryptionException();
1280 return m_xPackageStream
->getRawStream();
1283 //-----------------------------------------------
1284 ::rtl::OUString
OWriteStream_Impl::GetCommonRootPass()
1285 throw ( packages::NoEncryptionException
)
1287 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() ) ;
1289 if ( m_nStorageType
!= PACKAGE_STORAGE
|| !m_pParent
)
1290 throw packages::NoEncryptionException();
1292 return m_pParent
->GetCommonRootPass();
1295 //-----------------------------------------------
1296 void OWriteStream_Impl::InputStreamDisposed( OInputCompStream
* pStream
)
1298 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() );
1299 m_aInputStreamsList
.remove( pStream
);
1302 //-----------------------------------------------
1303 void OWriteStream_Impl::CreateReadonlyCopyBasedOnData( const uno::Reference
< io::XInputStream
>& xDataToCopy
, const uno::Sequence
< beans::PropertyValue
>& aProps
, sal_Bool
, uno::Reference
< io::XStream
>& xTargetStream
)
1305 uno::Reference
< io::XStream
> xTempFile
;
1306 if ( !xTargetStream
.is() )
1307 xTempFile
= uno::Reference
< io::XStream
>(
1308 m_xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
1311 xTempFile
= xTargetStream
;
1313 uno::Reference
< io::XSeekable
> xTempSeek( xTempFile
, uno::UNO_QUERY
);
1314 if ( !xTempSeek
.is() )
1315 throw uno::RuntimeException(); // TODO
1317 uno::Reference
< io::XOutputStream
> xTempOut
= xTempFile
->getOutputStream();
1318 if ( !xTempOut
.is() )
1319 throw uno::RuntimeException();
1321 if ( xDataToCopy
.is() )
1322 ::comphelper::OStorageHelper::CopyInputToOutput( xDataToCopy
, xTempOut
);
1324 xTempOut
->closeOutput();
1325 xTempSeek
->seek( 0 );
1327 uno::Reference
< io::XInputStream
> xInStream
= xTempFile
->getInputStream();
1328 if ( !xInStream
.is() )
1329 throw io::IOException();
1331 // TODO: remember last state of m_bUseCommonPass
1332 if ( !xTargetStream
.is() )
1333 xTargetStream
= uno::Reference
< io::XStream
> (
1334 static_cast< ::cppu::OWeakObject
* >(
1335 new OInputSeekStream( xInStream
, InsertOwnProps( aProps
, m_bUseCommonPass
), m_nStorageType
) ),
1336 uno::UNO_QUERY_THROW
);
1339 //-----------------------------------------------
1340 void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference
< io::XStream
>& xTargetStream
)
1342 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() );
1344 OSL_ENSURE( m_xPackageStream
.is(), "The source stream for copying is incomplete!\n" );
1345 if ( !m_xPackageStream
.is() )
1346 throw uno::RuntimeException();
1348 uno::Reference
< io::XInputStream
> xDataToCopy
;
1349 if ( IsEncrypted() )
1351 // an encrypted stream must contain input stream
1352 ::rtl::OUString aGlobalPass
;
1355 aGlobalPass
= GetCommonRootPass();
1357 catch( packages::NoEncryptionException
& )
1359 throw packages::WrongPasswordException();
1362 GetCopyOfLastCommit( xTargetStream
, aGlobalPass
);
1366 xDataToCopy
= m_xPackageStream
->getDataStream();
1368 // in case of new inserted package stream it is possible that input stream still was not set
1369 GetStreamProperties();
1371 CreateReadonlyCopyBasedOnData( xDataToCopy
, m_aProps
, m_bUseCommonPass
, xTargetStream
);
1375 //-----------------------------------------------
1376 void OWriteStream_Impl::GetCopyOfLastCommit( uno::Reference
< io::XStream
>& xTargetStream
, const ::rtl::OUString
& aPass
)
1378 ::osl::MutexGuard
aGuard( m_rMutexRef
->GetMutex() );
1380 OSL_ENSURE( m_xPackageStream
.is(), "The source stream for copying is incomplete!\n" );
1381 if ( !m_xPackageStream
.is() )
1382 throw uno::RuntimeException();
1384 if ( !IsEncrypted() )
1385 throw packages::NoEncryptionException();
1387 uno::Reference
< io::XInputStream
> xDataToCopy
;
1389 if ( m_bHasCachedPassword
)
1391 // TODO: introduce last commited cashed password information and use it here
1392 // that means "use common pass" also should be remembered on flash
1393 uno::Sequence
< sal_Int8
> aNewKey
= MakeKeyFromPass( aPass
, sal_True
);
1394 uno::Sequence
< sal_Int8
> aOldKey
= MakeKeyFromPass( aPass
, sal_False
);
1396 uno::Reference
< beans::XPropertySet
> xProps( m_xPackageStream
, uno::UNO_QUERY
);
1398 throw uno::RuntimeException();
1400 sal_Bool bEncr
= sal_False
;
1401 xProps
->getPropertyValue( ::rtl::OUString::createFromAscii( "Encrypted" ) ) >>= bEncr
;
1403 throw packages::NoEncryptionException();
1405 uno::Sequence
< sal_Int8
> aEncrKey
;
1406 xProps
->getPropertyValue( ::rtl::OUString::createFromAscii( "EncryptionKey" ) ) >>= aEncrKey
;
1407 if ( !SequencesEqual( aNewKey
, aEncrKey
) && !SequencesEqual( aOldKey
, aEncrKey
) )
1408 throw packages::WrongPasswordException();
1410 // the correct key must be set already
1411 xDataToCopy
= m_xPackageStream
->getDataStream();
1415 uno::Reference
< beans::XPropertySet
> xPropertySet( m_xPackageStream
, uno::UNO_QUERY
);
1416 SetEncryptionKeyProperty_Impl( xPropertySet
, MakeKeyFromPass( aPass
, sal_True
) );
1419 xDataToCopy
= m_xPackageStream
->getDataStream();
1421 if ( !xDataToCopy
.is() )
1423 OSL_ENSURE( sal_False
, "Encrypted ZipStream must already have input stream inside!\n" );
1424 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1427 catch( packages::WrongPasswordException
& )
1429 SetEncryptionKeyProperty_Impl( xPropertySet
, MakeKeyFromPass( aPass
, sal_False
) );
1431 xDataToCopy
= m_xPackageStream
->getDataStream();
1433 if ( !xDataToCopy
.is() )
1435 OSL_ENSURE( sal_False
, "Encrypted ZipStream must already have input stream inside!\n" );
1436 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1440 catch( uno::Exception
& )
1442 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1446 catch( uno::Exception
& )
1448 OSL_ENSURE( sal_False
, "Can't open encrypted stream!\n" );
1449 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1453 SetEncryptionKeyProperty_Impl( xPropertySet
, uno::Sequence
< sal_Int8
>() );
1456 // in case of new inserted package stream it is possible that input stream still was not set
1457 GetStreamProperties();
1459 CreateReadonlyCopyBasedOnData( xDataToCopy
, m_aProps
, m_bUseCommonPass
, xTargetStream
);
1462 //-----------------------------------------------
1463 void OWriteStream_Impl::CommitStreamRelInfo( const uno::Reference
< embed::XStorage
>& xRelStorage
, const ::rtl::OUString
& aOrigStreamName
, const ::rtl::OUString
& aNewStreamName
)
1465 // at this point of time the old stream must be already cleaned
1466 OSL_ENSURE( m_nStorageType
== OFOPXML_STORAGE
, "The method should be used only with OFOPXML format!\n" );
1468 if ( m_nStorageType
== OFOPXML_STORAGE
)
1470 OSL_ENSURE( aOrigStreamName
.getLength() && aNewStreamName
.getLength() && xRelStorage
.is(),
1471 "Wrong relation persistence information is provided!\n" );
1473 if ( !xRelStorage
.is() || !aOrigStreamName
.getLength() || !aNewStreamName
.getLength() )
1474 throw uno::RuntimeException();
1476 if ( m_nRelInfoStatus
== RELINFO_BROKEN
|| m_nRelInfoStatus
== RELINFO_CHANGED_BROKEN
)
1477 throw io::IOException(); // TODO:
1479 ::rtl::OUString aOrigRelStreamName
= aOrigStreamName
;
1480 aOrigRelStreamName
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
1482 ::rtl::OUString aNewRelStreamName
= aNewStreamName
;
1483 aNewRelStreamName
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
1485 sal_Bool bRenamed
= !aOrigRelStreamName
.equals( aNewRelStreamName
);
1486 if ( m_nRelInfoStatus
== RELINFO_CHANGED
1487 || m_nRelInfoStatus
== RELINFO_CHANGED_STREAM_READ
1488 || m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1490 if ( bRenamed
&& xRelStorage
->hasByName( aOrigRelStreamName
) )
1491 xRelStorage
->removeElement( aOrigRelStreamName
);
1493 if ( m_nRelInfoStatus
== RELINFO_CHANGED
)
1495 if ( m_aNewRelInfo
.getLength() )
1497 uno::Reference
< io::XStream
> xRelsStream
=
1498 xRelStorage
->openStreamElement( aNewRelStreamName
,
1499 embed::ElementModes::TRUNCATE
| embed::ElementModes::READWRITE
);
1501 uno::Reference
< io::XOutputStream
> xOutStream
= xRelsStream
->getOutputStream();
1502 if ( !xOutStream
.is() )
1503 throw uno::RuntimeException();
1505 ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence( xOutStream
, m_aNewRelInfo
, m_xFactory
);
1507 // set the mediatype
1508 uno::Reference
< beans::XPropertySet
> xPropSet( xRelsStream
, uno::UNO_QUERY_THROW
);
1509 xPropSet
->setPropertyValue(
1510 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1511 uno::makeAny( ::rtl::OUString(
1512 RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
1514 m_nRelInfoStatus
= RELINFO_READ
;
1517 else if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM_READ
1518 || m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1520 uno::Reference
< io::XStream
> xRelsStream
=
1521 xRelStorage
->openStreamElement( aNewRelStreamName
,
1522 embed::ElementModes::TRUNCATE
| embed::ElementModes::READWRITE
);
1524 uno::Reference
< io::XOutputStream
> xOutputStream
= xRelsStream
->getOutputStream();
1525 if ( !xOutputStream
.is() )
1526 throw uno::RuntimeException();
1528 uno::Reference
< io::XSeekable
> xSeek( m_xNewRelInfoStream
, uno::UNO_QUERY_THROW
);
1530 ::comphelper::OStorageHelper::CopyInputToOutput( m_xNewRelInfoStream
, xOutputStream
);
1533 // set the mediatype
1534 uno::Reference
< beans::XPropertySet
> xPropSet( xRelsStream
, uno::UNO_QUERY_THROW
);
1535 xPropSet
->setPropertyValue(
1536 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1537 uno::makeAny( ::rtl::OUString(
1538 RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
1540 if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1541 m_nRelInfoStatus
= RELINFO_NO_INIT
;
1544 // the information is already parsed and the stream is stored, no need in temporary stream any more
1545 m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
1546 m_nRelInfoStatus
= RELINFO_READ
;
1550 // the original stream makes no sence after this step
1551 m_xOrigRelInfoStream
= m_xNewRelInfoStream
;
1552 m_aOrigRelInfo
= m_aNewRelInfo
;
1553 m_bOrigRelInfoBroken
= sal_False
;
1554 m_aNewRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
1555 m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
1559 // the stream is not changed but it might be renamed
1560 if ( bRenamed
&& xRelStorage
->hasByName( aOrigRelStreamName
) )
1561 xRelStorage
->renameElement( aOrigRelStreamName
, aNewRelStreamName
);
1566 //===============================================
1567 // OWriteStream implementation
1568 //===============================================
1570 //-----------------------------------------------
1571 OWriteStream::OWriteStream( OWriteStream_Impl
* pImpl
, sal_Bool bTransacted
)
1573 , m_bInStreamDisconnected( sal_False
)
1574 , m_bInitOnDemand( sal_True
)
1575 , m_bTransacted( bTransacted
)
1577 OSL_ENSURE( pImpl
, "No base implementation!\n" );
1578 OSL_ENSURE( m_pImpl
->m_rMutexRef
.Is(), "No mutex!\n" );
1580 if ( !m_pImpl
|| !m_pImpl
->m_rMutexRef
.Is() )
1581 throw uno::RuntimeException(); // just a disaster
1583 m_pData
= new WSInternalData_Impl( pImpl
->m_rMutexRef
, m_pImpl
->m_nStorageType
);
1586 //-----------------------------------------------
1587 OWriteStream::OWriteStream( OWriteStream_Impl
* pImpl
, uno::Reference
< io::XStream
> xStream
, sal_Bool bTransacted
)
1589 , m_bInStreamDisconnected( sal_False
)
1590 , m_bInitOnDemand( sal_False
)
1591 , m_bTransacted( bTransacted
)
1593 OSL_ENSURE( pImpl
&& xStream
.is(), "No base implementation!\n" );
1594 OSL_ENSURE( m_pImpl
->m_rMutexRef
.Is(), "No mutex!\n" );
1596 if ( !m_pImpl
|| !m_pImpl
->m_rMutexRef
.Is() )
1597 throw uno::RuntimeException(); // just a disaster
1599 m_pData
= new WSInternalData_Impl( pImpl
->m_rMutexRef
, m_pImpl
->m_nStorageType
);
1603 m_xInStream
= xStream
->getInputStream();
1604 m_xOutStream
= xStream
->getOutputStream();
1605 m_xSeekable
= uno::Reference
< io::XSeekable
>( xStream
, uno::UNO_QUERY
);
1606 OSL_ENSURE( m_xInStream
.is() && m_xOutStream
.is() && m_xSeekable
.is(), "Stream implementation is incomplete!\n" );
1610 //-----------------------------------------------
1611 OWriteStream::~OWriteStream()
1614 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
1621 catch( uno::RuntimeException
& )
1626 if ( m_pData
&& m_pData
->m_pTypeCollection
)
1627 delete m_pData
->m_pTypeCollection
;
1633 //-----------------------------------------------
1634 void OWriteStream::CheckInitOnDemand()
1637 throw lang::DisposedException();
1639 if ( m_bInitOnDemand
)
1641 RTL_LOGFILE_CONTEXT( aLog
, "package (mv76033) OWriteStream::CheckInitOnDemand, initializing" );
1642 uno::Reference
< io::XStream
> xStream
= m_pImpl
->GetTempFileAsStream();
1645 m_xInStream
= xStream
->getInputStream();
1646 m_xOutStream
= xStream
->getOutputStream();
1647 m_xSeekable
= uno::Reference
< io::XSeekable
>( xStream
, uno::UNO_QUERY
);
1648 OSL_ENSURE( m_xInStream
.is() && m_xOutStream
.is() && m_xSeekable
.is(), "Stream implementation is incomplete!\n" );
1650 m_bInitOnDemand
= sal_False
;
1655 //-----------------------------------------------
1656 void OWriteStream::CopyToStreamInternally_Impl( const uno::Reference
< io::XStream
>& xDest
)
1658 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
1660 CheckInitOnDemand();
1662 if ( !m_xInStream
.is() )
1663 throw uno::RuntimeException();
1665 if ( !m_xSeekable
.is() )
1666 throw uno::RuntimeException();
1668 uno::Reference
< beans::XPropertySet
> xDestProps( xDest
, uno::UNO_QUERY
);
1669 if ( !xDestProps
.is() )
1670 throw uno::RuntimeException(); //TODO
1672 uno::Reference
< io::XOutputStream
> xDestOutStream
= xDest
->getOutputStream();
1673 if ( !xDestOutStream
.is() )
1674 throw io::IOException(); // TODO
1676 sal_Int64 nCurPos
= m_xSeekable
->getPosition();
1677 m_xSeekable
->seek( 0 );
1679 uno::Exception eThrown
;
1680 sal_Bool bThrown
= sal_False
;
1682 ::comphelper::OStorageHelper::CopyInputToOutput( m_xInStream
, xDestOutStream
);
1684 catch ( uno::Exception
& e
)
1690 // position-related section below is critical
1691 // if it fails the stream will become invalid
1693 m_xSeekable
->seek( nCurPos
);
1695 catch ( uno::Exception
& )
1697 // TODO: set the stoream in invalid state or dispose
1698 OSL_ENSURE( sal_False
, "The stream become invalid during copiing!\n" );
1699 throw uno::RuntimeException();
1705 // now the properties can be copied
1706 // the order of the properties setting is not important for StorageStream API
1707 ::rtl::OUString aPropName
= ::rtl::OUString::createFromAscii( "Compressed" );
1708 xDestProps
->setPropertyValue( aPropName
, getPropertyValue( aPropName
) );
1709 if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
|| m_pData
->m_nStorageType
== OFOPXML_STORAGE
)
1711 aPropName
= ::rtl::OUString::createFromAscii( "MediaType" );
1712 xDestProps
->setPropertyValue( aPropName
, getPropertyValue( aPropName
) );
1714 if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
)
1716 aPropName
= ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" );
1717 xDestProps
->setPropertyValue( aPropName
, getPropertyValue( aPropName
) );
1722 //-----------------------------------------------
1723 void OWriteStream::ModifyParentUnlockMutex_Impl( ::osl::ResettableMutexGuard
& aGuard
)
1725 if ( m_pImpl
->m_pParent
)
1727 if ( m_pImpl
->m_pParent
->m_pAntiImpl
)
1729 uno::Reference
< util::XModifiable
> xParentModif( (util::XModifiable
*)(m_pImpl
->m_pParent
->m_pAntiImpl
) );
1731 xParentModif
->setModified( sal_True
);
1734 m_pImpl
->m_pParent
->m_bIsModified
= sal_True
;
1738 //-----------------------------------------------
1739 uno::Any SAL_CALL
OWriteStream::queryInterface( const uno::Type
& rType
)
1740 throw( uno::RuntimeException
)
1744 // common interfaces
1745 aReturn
<<= ::cppu::queryInterface
1747 , static_cast<lang::XTypeProvider
*> ( this )
1748 , static_cast<io::XInputStream
*> ( this )
1749 , static_cast<io::XOutputStream
*> ( this )
1750 , static_cast<io::XStream
*> ( this )
1751 , static_cast<embed::XExtendedStorageStream
*> ( this )
1752 , static_cast<io::XSeekable
*> ( this )
1753 , static_cast<io::XTruncate
*> ( this )
1754 , static_cast<lang::XComponent
*> ( this )
1755 , static_cast<beans::XPropertySet
*> ( this ) );
1757 if ( aReturn
.hasValue() == sal_True
)
1760 if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
)
1762 aReturn
<<= ::cppu::queryInterface
1764 , static_cast<embed::XEncryptionProtectedSource
*> ( this ) );
1766 else if ( m_pData
->m_nStorageType
== OFOPXML_STORAGE
)
1768 aReturn
<<= ::cppu::queryInterface
1770 , static_cast<embed::XRelationshipAccess
*> ( this ) );
1773 if ( aReturn
.hasValue() == sal_True
)
1776 if ( m_bTransacted
)
1778 aReturn
<<= ::cppu::queryInterface
1780 , static_cast<embed::XTransactedObject
*> ( this )
1781 , static_cast<embed::XTransactionBroadcaster
*> ( this ) );
1783 if ( aReturn
.hasValue() == sal_True
)
1787 return OWeakObject::queryInterface( rType
);
1790 //-----------------------------------------------
1791 void SAL_CALL
OWriteStream::acquire() throw()
1793 OWeakObject::acquire();
1796 //-----------------------------------------------
1797 void SAL_CALL
OWriteStream::release() throw()
1799 OWeakObject::release();
1802 //-----------------------------------------------
1803 uno::Sequence
< uno::Type
> SAL_CALL
OWriteStream::getTypes()
1804 throw( uno::RuntimeException
)
1806 if ( m_pData
->m_pTypeCollection
== NULL
)
1808 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
1810 if ( m_pData
->m_pTypeCollection
== NULL
)
1812 if ( m_bTransacted
)
1814 if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
)
1816 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
1817 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
1818 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
1819 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
1820 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
1821 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
1822 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
1823 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
1824 , ::getCppuType( ( const uno::Reference
< embed::XEncryptionProtectedSource
>* )NULL
)
1825 , ::getCppuType( ( const uno::Reference
< embed::XExtendedStorageStream
>* )NULL
)
1826 , ::getCppuType( ( const uno::Reference
< embed::XTransactedObject
>* )NULL
)
1827 , ::getCppuType( ( const uno::Reference
< embed::XTransactionBroadcaster
>* )NULL
)
1828 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
1830 else if ( m_pData
->m_nStorageType
== OFOPXML_STORAGE
)
1832 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
1833 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
1834 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
1835 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
1836 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
1837 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
1838 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
1839 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
1840 , ::getCppuType( ( const uno::Reference
< embed::XRelationshipAccess
>* )NULL
)
1841 , ::getCppuType( ( const uno::Reference
< embed::XExtendedStorageStream
>* )NULL
)
1842 , ::getCppuType( ( const uno::Reference
< embed::XTransactedObject
>* )NULL
)
1843 , ::getCppuType( ( const uno::Reference
< embed::XTransactionBroadcaster
>* )NULL
)
1844 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
1846 else // if ( m_pData->m_nStorageType == ZIP_STORAGE )
1848 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
1849 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
1850 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
1851 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
1852 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
1853 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
1854 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
1855 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
1856 , ::getCppuType( ( const uno::Reference
< embed::XExtendedStorageStream
>* )NULL
)
1857 , ::getCppuType( ( const uno::Reference
< embed::XTransactedObject
>* )NULL
)
1858 , ::getCppuType( ( const uno::Reference
< embed::XTransactionBroadcaster
>* )NULL
)
1859 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
1864 if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
)
1866 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
1867 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
1868 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
1869 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
1870 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
1871 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
1872 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
1873 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
1874 , ::getCppuType( ( const uno::Reference
< embed::XEncryptionProtectedSource
>* )NULL
)
1875 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
1877 else if ( m_pData
->m_nStorageType
== OFOPXML_STORAGE
)
1879 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
1880 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
1881 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
1882 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
1883 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
1884 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
1885 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
1886 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
1887 , ::getCppuType( ( const uno::Reference
< embed::XRelationshipAccess
>* )NULL
)
1888 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
1890 else // if ( m_pData->m_nStorageType == ZIP_STORAGE )
1892 m_pData
->m_pTypeCollection
= new ::cppu::OTypeCollection
1893 ( ::getCppuType( ( const uno::Reference
< lang::XTypeProvider
>* )NULL
)
1894 , ::getCppuType( ( const uno::Reference
< io::XInputStream
>* )NULL
)
1895 , ::getCppuType( ( const uno::Reference
< io::XOutputStream
>* )NULL
)
1896 , ::getCppuType( ( const uno::Reference
< io::XStream
>* )NULL
)
1897 , ::getCppuType( ( const uno::Reference
< io::XSeekable
>* )NULL
)
1898 , ::getCppuType( ( const uno::Reference
< io::XTruncate
>* )NULL
)
1899 , ::getCppuType( ( const uno::Reference
< lang::XComponent
>* )NULL
)
1900 , ::getCppuType( ( const uno::Reference
< beans::XPropertySet
>* )NULL
) );
1906 return m_pData
->m_pTypeCollection
->getTypes() ;
1909 //-----------------------------------------------
1910 uno::Sequence
< sal_Int8
> SAL_CALL
OWriteStream::getImplementationId()
1911 throw( uno::RuntimeException
)
1913 static ::cppu::OImplementationId
* pID
= NULL
;
1917 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() ) ;
1921 static ::cppu::OImplementationId
aID( sal_False
) ;
1926 return pID
->getImplementationId() ;
1930 //-----------------------------------------------
1931 sal_Int32 SAL_CALL
OWriteStream::readBytes( uno::Sequence
< sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
1932 throw ( io::NotConnectedException
,
1933 io::BufferSizeExceededException
,
1935 uno::RuntimeException
)
1937 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
1939 CheckInitOnDemand();
1942 throw lang::DisposedException();
1944 if ( !m_xInStream
.is() )
1945 throw io::NotConnectedException();
1947 return m_xInStream
->readBytes( aData
, nBytesToRead
);
1950 //-----------------------------------------------
1951 sal_Int32 SAL_CALL
OWriteStream::readSomeBytes( uno::Sequence
< sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
1952 throw ( io::NotConnectedException
,
1953 io::BufferSizeExceededException
,
1955 uno::RuntimeException
)
1957 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
1959 CheckInitOnDemand();
1962 throw lang::DisposedException();
1964 if ( !m_xInStream
.is() )
1965 throw io::NotConnectedException();
1967 return m_xInStream
->readSomeBytes( aData
, nMaxBytesToRead
);
1970 //-----------------------------------------------
1971 void SAL_CALL
OWriteStream::skipBytes( sal_Int32 nBytesToSkip
)
1972 throw ( io::NotConnectedException
,
1973 io::BufferSizeExceededException
,
1975 uno::RuntimeException
)
1977 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
1979 CheckInitOnDemand();
1982 throw lang::DisposedException();
1984 if ( !m_xInStream
.is() )
1985 throw io::NotConnectedException();
1987 m_xInStream
->skipBytes( nBytesToSkip
);
1990 //-----------------------------------------------
1991 sal_Int32 SAL_CALL
OWriteStream::available( )
1992 throw ( io::NotConnectedException
,
1994 uno::RuntimeException
)
1996 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
1998 CheckInitOnDemand();
2001 throw lang::DisposedException();
2003 if ( !m_xInStream
.is() )
2004 throw io::NotConnectedException();
2006 return m_xInStream
->available();
2010 //-----------------------------------------------
2011 void SAL_CALL
OWriteStream::closeInput( )
2012 throw ( io::NotConnectedException
,
2014 uno::RuntimeException
)
2016 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2019 throw lang::DisposedException();
2021 if ( !m_bInitOnDemand
&& ( m_bInStreamDisconnected
|| !m_xInStream
.is() ) )
2022 throw io::NotConnectedException();
2024 // the input part of the stream stays open for internal purposes ( to allow reading during copiing )
2025 // since it can not be reopened until output part is closed, it will be closed with output part.
2026 m_bInStreamDisconnected
= sal_True
;
2027 // m_xInStream->closeInput();
2028 // m_xInStream = uno::Reference< io::XInputStream >();
2030 if ( !m_xOutStream
.is() )
2034 //-----------------------------------------------
2035 uno::Reference
< io::XInputStream
> SAL_CALL
OWriteStream::getInputStream()
2036 throw ( uno::RuntimeException
)
2038 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2041 throw lang::DisposedException();
2043 if ( !m_bInitOnDemand
&& ( m_bInStreamDisconnected
|| !m_xInStream
.is() ) )
2044 return uno::Reference
< io::XInputStream
>();
2046 return uno::Reference
< io::XInputStream
>( static_cast< io::XInputStream
* >( this ), uno::UNO_QUERY
);
2049 //-----------------------------------------------
2050 uno::Reference
< io::XOutputStream
> SAL_CALL
OWriteStream::getOutputStream()
2051 throw ( uno::RuntimeException
)
2053 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2055 CheckInitOnDemand();
2058 throw lang::DisposedException();
2060 if ( !m_xOutStream
.is() )
2061 return uno::Reference
< io::XOutputStream
>();
2063 return uno::Reference
< io::XOutputStream
>( static_cast< io::XOutputStream
* >( this ), uno::UNO_QUERY
);
2066 //-----------------------------------------------
2067 void SAL_CALL
OWriteStream::writeBytes( const uno::Sequence
< sal_Int8
>& aData
)
2068 throw ( io::NotConnectedException
,
2069 io::BufferSizeExceededException
,
2071 uno::RuntimeException
)
2073 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2075 CheckInitOnDemand();
2078 throw lang::DisposedException();
2080 if ( !m_xOutStream
.is() )
2081 throw io::NotConnectedException();
2083 m_xOutStream
->writeBytes( aData
);
2084 m_pImpl
->m_bHasDataToFlush
= sal_True
;
2086 ModifyParentUnlockMutex_Impl( aGuard
);
2089 //-----------------------------------------------
2090 void SAL_CALL
OWriteStream::flush()
2091 throw ( io::NotConnectedException
,
2092 io::BufferSizeExceededException
,
2094 uno::RuntimeException
)
2096 // In case stream is flushed it's current version becomes visible
2097 // to the parent storage. Usually parent storage flushes the stream
2098 // during own commit but a user can explicitly flush the stream
2099 // so the changes will be available through cloning functionality.
2101 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2104 throw lang::DisposedException();
2106 if ( !m_bInitOnDemand
)
2108 if ( !m_xOutStream
.is() )
2109 throw io::NotConnectedException();
2111 m_xOutStream
->flush();
2116 //-----------------------------------------------
2117 void OWriteStream::CloseOutput_Impl()
2119 // all the checks must be done in calling method
2121 m_xOutStream
->closeOutput();
2122 m_xOutStream
= uno::Reference
< io::XOutputStream
>();
2124 if ( !m_bInitOnDemand
)
2126 // after the stream is disposed it can be commited
2127 // so transport correct size property
2128 if ( !m_xSeekable
.is() )
2129 throw uno::RuntimeException();
2131 for ( sal_Int32 nInd
= 0; nInd
< m_pImpl
->m_aProps
.getLength(); nInd
++ )
2133 if ( m_pImpl
->m_aProps
[nInd
].Name
.equalsAscii( "Size" ) )
2134 m_pImpl
->m_aProps
[nInd
].Value
<<= ((sal_Int32
)m_xSeekable
->getLength());
2139 //-----------------------------------------------
2140 void SAL_CALL
OWriteStream::closeOutput()
2141 throw ( io::NotConnectedException
,
2142 io::BufferSizeExceededException
,
2144 uno::RuntimeException
)
2146 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2148 CheckInitOnDemand();
2151 throw lang::DisposedException();
2153 if ( !m_xOutStream
.is() )
2154 throw io::NotConnectedException();
2158 if ( m_bInStreamDisconnected
|| !m_xInStream
.is() )
2162 //-----------------------------------------------
2163 void SAL_CALL
OWriteStream::seek( sal_Int64 location
)
2164 throw ( lang::IllegalArgumentException
,
2166 uno::RuntimeException
)
2168 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2170 CheckInitOnDemand();
2173 throw lang::DisposedException();
2175 if ( !m_xSeekable
.is() )
2176 throw uno::RuntimeException();
2178 m_xSeekable
->seek( location
);
2181 //-----------------------------------------------
2182 sal_Int64 SAL_CALL
OWriteStream::getPosition()
2183 throw ( io::IOException
,
2184 uno::RuntimeException
)
2186 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2188 CheckInitOnDemand();
2191 throw lang::DisposedException();
2193 if ( !m_xSeekable
.is() )
2194 throw uno::RuntimeException();
2196 return m_xSeekable
->getPosition();
2199 //-----------------------------------------------
2200 sal_Int64 SAL_CALL
OWriteStream::getLength()
2201 throw ( io::IOException
,
2202 uno::RuntimeException
)
2204 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2206 CheckInitOnDemand();
2209 throw lang::DisposedException();
2211 if ( !m_xSeekable
.is() )
2212 throw uno::RuntimeException();
2214 return m_xSeekable
->getLength();
2217 //-----------------------------------------------
2218 void SAL_CALL
OWriteStream::truncate()
2219 throw ( io::IOException
,
2220 uno::RuntimeException
)
2222 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2224 CheckInitOnDemand();
2227 throw lang::DisposedException();
2229 if ( !m_xOutStream
.is() )
2230 throw uno::RuntimeException();
2232 uno::Reference
< io::XTruncate
> xTruncate( m_xOutStream
, uno::UNO_QUERY
);
2234 if ( !xTruncate
.is() )
2236 OSL_ENSURE( sal_False
, "The output stream must support XTruncate interface!\n" );
2237 throw uno::RuntimeException();
2240 xTruncate
->truncate();
2242 m_pImpl
->m_bHasDataToFlush
= sal_True
;
2244 ModifyParentUnlockMutex_Impl( aGuard
);
2247 //-----------------------------------------------
2248 void SAL_CALL
OWriteStream::dispose()
2249 throw ( uno::RuntimeException
)
2251 // should be an internal method since it can be called only from parent storage
2253 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2256 throw lang::DisposedException();
2258 if ( m_xOutStream
.is() )
2261 if ( m_xInStream
.is() )
2263 m_xInStream
->closeInput();
2264 m_xInStream
= uno::Reference
< io::XInputStream
>();
2267 m_pImpl
->m_pAntiImpl
= NULL
;
2269 if ( !m_bInitOnDemand
)
2273 if ( !m_bTransacted
)
2279 // throw away all the changes
2283 catch( uno::Exception
& )
2285 uno::Any
aCaught( ::cppu::getCaughtException() );
2286 throw lang::WrappedTargetRuntimeException(
2287 ::rtl::OUString::createFromAscii( "Can not commit/revert the storage!\n" ),
2288 uno::Reference
< uno::XInterface
>( static_cast< OWeakObject
* >( this ),
2297 // the listener might try to get rid of parent storage, and the storage would delete this object;
2298 // for now the listener is just notified at the end of the method to workaround the problem
2299 // in future a more elegant way should be found
2301 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
2302 m_pData
->m_aListenersContainer
.disposeAndClear( aSource
);
2305 //-----------------------------------------------
2306 void SAL_CALL
OWriteStream::addEventListener(
2307 const uno::Reference
< lang::XEventListener
>& xListener
)
2308 throw ( uno::RuntimeException
)
2310 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2313 throw lang::DisposedException();
2315 m_pData
->m_aListenersContainer
.addInterface( ::getCppuType((const uno::Reference
< lang::XEventListener
>*)0),
2319 //-----------------------------------------------
2320 void SAL_CALL
OWriteStream::removeEventListener(
2321 const uno::Reference
< lang::XEventListener
>& xListener
)
2322 throw ( uno::RuntimeException
)
2324 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2327 throw lang::DisposedException();
2329 m_pData
->m_aListenersContainer
.removeInterface( ::getCppuType((const uno::Reference
< lang::XEventListener
>*)0),
2333 //-----------------------------------------------
2334 void SAL_CALL
OWriteStream::setEncryptionPassword( const ::rtl::OUString
& aPass
)
2335 throw ( uno::RuntimeException
,
2338 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2340 CheckInitOnDemand();
2343 throw lang::DisposedException();
2345 OSL_ENSURE( m_pImpl
->m_xPackageStream
.is(), "No package stream is set!\n" );
2347 m_pImpl
->SetEncryptedWithPass( aPass
);
2349 ModifyParentUnlockMutex_Impl( aGuard
);
2352 //-----------------------------------------------
2353 void SAL_CALL
OWriteStream::removeEncryption()
2354 throw ( uno::RuntimeException
,
2357 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2359 CheckInitOnDemand();
2362 throw lang::DisposedException();
2364 OSL_ENSURE( m_pImpl
->m_xPackageStream
.is(), "No package stream is set!\n" );
2366 m_pImpl
->SetDecrypted();
2368 ModifyParentUnlockMutex_Impl( aGuard
);
2371 //-----------------------------------------------
2372 sal_Bool SAL_CALL
OWriteStream::hasByID( const ::rtl::OUString
& sID
)
2373 throw ( io::IOException
,
2374 uno::RuntimeException
)
2376 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2379 throw lang::DisposedException();
2381 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2382 throw uno::RuntimeException();
2386 getRelationshipByID( sID
);
2389 catch( container::NoSuchElementException
& )
2395 //-----------------------------------------------
2396 ::rtl::OUString SAL_CALL
OWriteStream::getTargetByID( const ::rtl::OUString
& sID
)
2397 throw ( container::NoSuchElementException
,
2399 uno::RuntimeException
)
2401 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2404 throw lang::DisposedException();
2406 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2407 throw uno::RuntimeException();
2409 uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
2410 for ( sal_Int32 nInd
= 0; nInd
< aSeq
.getLength(); nInd
++ )
2411 if ( aSeq
[nInd
].First
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Target" ) ) )
2412 return aSeq
[nInd
].Second
;
2414 return ::rtl::OUString();
2417 //-----------------------------------------------
2418 ::rtl::OUString SAL_CALL
OWriteStream::getTypeByID( const ::rtl::OUString
& sID
)
2419 throw ( container::NoSuchElementException
,
2421 uno::RuntimeException
)
2423 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2426 throw lang::DisposedException();
2428 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2429 throw uno::RuntimeException();
2431 uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
2432 for ( sal_Int32 nInd
= 0; nInd
< aSeq
.getLength(); nInd
++ )
2433 if ( aSeq
[nInd
].First
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
2434 return aSeq
[nInd
].Second
;
2436 return ::rtl::OUString();
2439 //-----------------------------------------------
2440 uno::Sequence
< beans::StringPair
> SAL_CALL
OWriteStream::getRelationshipByID( const ::rtl::OUString
& sID
)
2441 throw ( container::NoSuchElementException
,
2443 uno::RuntimeException
)
2445 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2448 throw lang::DisposedException();
2450 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2451 throw uno::RuntimeException();
2453 // TODO/LATER: in future the unification of the ID could be checked
2454 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
2455 for ( sal_Int32 nInd1
= 0; nInd1
< aSeq
.getLength(); nInd1
++ )
2456 for ( sal_Int32 nInd2
= 0; nInd2
< aSeq
[nInd1
].getLength(); nInd2
++ )
2457 if ( aSeq
[nInd1
][nInd2
].First
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
2459 if ( aSeq
[nInd1
][nInd2
].Second
.equals( sID
) )
2464 throw container::NoSuchElementException();
2467 //-----------------------------------------------
2468 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OWriteStream::getRelationshipsByType( const ::rtl::OUString
& sType
)
2469 throw ( io::IOException
,
2470 uno::RuntimeException
)
2472 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2475 throw lang::DisposedException();
2477 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2478 throw uno::RuntimeException();
2480 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aResult
;
2481 sal_Int32 nEntriesNum
= 0;
2483 // TODO/LATER: in future the unification of the ID could be checked
2484 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
2485 for ( sal_Int32 nInd1
= 0; nInd1
< aSeq
.getLength(); nInd1
++ )
2486 for ( sal_Int32 nInd2
= 0; nInd2
< aSeq
[nInd1
].getLength(); nInd2
++ )
2487 if ( aSeq
[nInd1
][nInd2
].First
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
2489 if ( aSeq
[nInd1
][nInd2
].Second
.equals( sType
) )
2491 aResult
.realloc( nEntriesNum
);
2492 aResult
[nEntriesNum
-1] = aSeq
[nInd1
];
2500 //-----------------------------------------------
2501 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OWriteStream::getAllRelationships()
2502 throw (io::IOException
, uno::RuntimeException
)
2504 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2507 throw lang::DisposedException();
2509 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2510 throw uno::RuntimeException();
2512 return m_pImpl
->GetAllRelationshipsIfAny();
2515 //-----------------------------------------------
2516 void SAL_CALL
OWriteStream::insertRelationshipByID( const ::rtl::OUString
& sID
, const uno::Sequence
< beans::StringPair
>& aEntry
, ::sal_Bool bReplace
)
2517 throw ( container::ElementExistException
,
2519 uno::RuntimeException
)
2521 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2524 throw lang::DisposedException();
2526 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2527 throw uno::RuntimeException();
2529 ::rtl::OUString
aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
2531 sal_Int32 nIDInd
= -1;
2533 // TODO/LATER: in future the unification of the ID could be checked
2534 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
2535 for ( sal_Int32 nInd1
= 0; nInd1
< aSeq
.getLength(); nInd1
++ )
2536 for ( sal_Int32 nInd2
= 0; nInd2
< aSeq
[nInd1
].getLength(); nInd2
++ )
2537 if ( aSeq
[nInd1
][nInd2
].First
.equals( aIDTag
) )
2539 if ( aSeq
[nInd1
][nInd2
].Second
.equals( sID
) )
2545 if ( nIDInd
== -1 || bReplace
)
2549 nIDInd
= aSeq
.getLength();
2550 aSeq
.realloc( nIDInd
+ 1 );
2553 aSeq
[nIDInd
].realloc( aEntry
.getLength() + 1 );
2555 aSeq
[nIDInd
][0].First
= aIDTag
;
2556 aSeq
[nIDInd
][0].Second
= sID
;
2557 sal_Int32 nIndTarget
= 1;
2558 for ( sal_Int32 nIndOrig
= 0;
2559 nIndOrig
< aEntry
.getLength();
2562 if ( !aEntry
[nIndOrig
].First
.equals( aIDTag
) )
2563 aSeq
[nIDInd
][nIndTarget
++] = aEntry
[nIndOrig
];
2566 aSeq
[nIDInd
].realloc( nIndTarget
);
2569 throw container::ElementExistException(); // TODO
2572 m_pImpl
->m_aNewRelInfo
= aSeq
;
2573 m_pImpl
->m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
2574 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
2577 //-----------------------------------------------
2578 void SAL_CALL
OWriteStream::removeRelationshipByID( const ::rtl::OUString
& sID
)
2579 throw ( container::NoSuchElementException
,
2581 uno::RuntimeException
)
2583 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2586 throw lang::DisposedException();
2588 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2589 throw uno::RuntimeException();
2591 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
2592 for ( sal_Int32 nInd1
= 0; nInd1
< aSeq
.getLength(); nInd1
++ )
2593 for ( sal_Int32 nInd2
= 0; nInd2
< aSeq
[nInd1
].getLength(); nInd2
++ )
2594 if ( aSeq
[nInd1
][nInd2
].First
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
2596 if ( aSeq
[nInd1
][nInd2
].Second
.equals( sID
) )
2598 sal_Int32 nLength
= aSeq
.getLength();
2599 aSeq
[nInd1
] = aSeq
[nLength
-1];
2600 aSeq
.realloc( nLength
- 1 );
2602 m_pImpl
->m_aNewRelInfo
= aSeq
;
2603 m_pImpl
->m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
2604 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
2606 // TODO/LATER: in future the unification of the ID could be checked
2613 throw container::NoSuchElementException();
2616 //-----------------------------------------------
2617 void SAL_CALL
OWriteStream::insertRelationships( const uno::Sequence
< uno::Sequence
< beans::StringPair
> >& aEntries
, ::sal_Bool bReplace
)
2618 throw ( container::ElementExistException
,
2620 uno::RuntimeException
)
2622 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2625 throw lang::DisposedException();
2627 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2628 throw uno::RuntimeException();
2630 ::rtl::OUString
aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
2631 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
2632 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aResultSeq( aSeq
.getLength() + aEntries
.getLength() );
2633 sal_Int32 nResultInd
= 0;
2635 for ( sal_Int32 nIndTarget1
= 0; nIndTarget1
< aSeq
.getLength(); nIndTarget1
++ )
2636 for ( sal_Int32 nIndTarget2
= 0; nIndTarget2
< aSeq
[nIndTarget1
].getLength(); nIndTarget2
++ )
2637 if ( aSeq
[nIndTarget1
][nIndTarget2
].First
.equals( aIDTag
) )
2639 sal_Int32 nIndSourceSame
= -1;
2641 for ( sal_Int32 nIndSource1
= 0; nIndSource1
< aEntries
.getLength(); nIndSource1
++ )
2642 for ( sal_Int32 nIndSource2
= 0; nIndSource2
< aEntries
[nIndSource1
].getLength(); nIndSource2
++ )
2644 if ( aEntries
[nIndSource1
][nIndSource2
].First
.equals( aIDTag
) )
2646 if ( aEntries
[nIndSource1
][nIndSource2
].Second
.equals( aSeq
[nIndTarget1
][nIndTarget2
].Second
) )
2649 throw container::ElementExistException();
2651 nIndSourceSame
= nIndSource1
;
2658 if ( nIndSourceSame
== -1 )
2660 // no such element in the provided sequence
2661 aResultSeq
[nResultInd
++] = aSeq
[nIndTarget1
];
2667 for ( sal_Int32 nIndSource1
= 0; nIndSource1
< aEntries
.getLength(); nIndSource1
++ )
2669 aResultSeq
[nResultInd
].realloc( aEntries
[nIndSource1
].getLength() );
2670 sal_Bool bHasID
= sal_False
;
2671 sal_Int32 nResInd2
= 1;
2673 for ( sal_Int32 nIndSource2
= 0; nIndSource2
< aEntries
[nIndSource1
].getLength(); nIndSource2
++ )
2674 if ( aEntries
[nIndSource1
][nIndSource2
].First
.equals( aIDTag
) )
2676 aResultSeq
[nResultInd
][0] = aEntries
[nIndSource1
][nIndSource2
];
2679 else if ( nResInd2
< aResultSeq
[nResultInd
].getLength() )
2680 aResultSeq
[nResultInd
][nResInd2
++] = aEntries
[nIndSource1
][nIndSource2
];
2682 throw io::IOException(); // TODO: illegal relation ( no ID )
2685 throw io::IOException(); // TODO: illegal relations
2690 aResultSeq
.realloc( nResultInd
);
2691 m_pImpl
->m_aNewRelInfo
= aResultSeq
;
2692 m_pImpl
->m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
2693 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
2696 //-----------------------------------------------
2697 void SAL_CALL
OWriteStream::clearRelationships()
2698 throw ( io::IOException
,
2699 uno::RuntimeException
)
2701 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2704 throw lang::DisposedException();
2706 if ( m_pData
->m_nStorageType
!= OFOPXML_STORAGE
)
2707 throw uno::RuntimeException();
2709 m_pImpl
->m_aNewRelInfo
.realloc( 0 );
2710 m_pImpl
->m_xNewRelInfoStream
= uno::Reference
< io::XInputStream
>();
2711 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
2714 //-----------------------------------------------
2715 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
OWriteStream::getPropertySetInfo()
2716 throw ( uno::RuntimeException
)
2718 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2721 return uno::Reference
< beans::XPropertySetInfo
>();
2724 //-----------------------------------------------
2725 void SAL_CALL
OWriteStream::setPropertyValue( const ::rtl::OUString
& aPropertyName
, const uno::Any
& aValue
)
2726 throw ( beans::UnknownPropertyException
,
2727 beans::PropertyVetoException
,
2728 lang::IllegalArgumentException
,
2729 lang::WrappedTargetException
,
2730 uno::RuntimeException
)
2732 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2735 throw lang::DisposedException();
2737 m_pImpl
->GetStreamProperties();
2739 if ( ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
|| m_pData
->m_nStorageType
== OFOPXML_STORAGE
)
2740 && aPropertyName
.equalsAscii( "MediaType" )
2741 || aPropertyName
.equalsAscii( "Compressed" ) )
2743 for ( sal_Int32 nInd
= 0; nInd
< m_pImpl
->m_aProps
.getLength(); nInd
++ )
2745 if ( aPropertyName
.equals( m_pImpl
->m_aProps
[nInd
].Name
) )
2746 m_pImpl
->m_aProps
[nInd
].Value
= aValue
;
2749 else if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
2750 && aPropertyName
.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
2752 sal_Bool bUseCommonPass
= sal_False
;
2753 if ( aValue
>>= bUseCommonPass
)
2755 if ( m_bInitOnDemand
&& m_pImpl
->m_bHasInsertedStreamOptimization
)
2757 // the data stream is provided to the packagestream directly
2758 m_pImpl
->m_bUseCommonPass
= bUseCommonPass
;
2760 else if ( bUseCommonPass
)
2762 if ( !m_pImpl
->m_bUseCommonPass
)
2764 m_pImpl
->SetDecrypted();
2765 m_pImpl
->m_bUseCommonPass
= sal_True
;
2769 m_pImpl
->m_bUseCommonPass
= sal_False
;
2772 throw lang::IllegalArgumentException(); //TODO
2774 else if ( m_pData
->m_nStorageType
== OFOPXML_STORAGE
&& aPropertyName
.equalsAscii( "RelationsInfoStream" ) )
2776 uno::Reference
< io::XInputStream
> xInRelStream
;
2777 if ( ( aValue
>>= xInRelStream
) && xInRelStream
.is() )
2779 uno::Reference
< io::XSeekable
> xSeek( xInRelStream
, uno::UNO_QUERY
);
2782 // currently this is an internal property that is used for optimization
2783 // and the stream must support XSeekable interface
2784 // TODO/LATER: in future it can be changed if property is used from outside
2785 throw lang::IllegalArgumentException(); // TODO
2788 m_pImpl
->m_xNewRelInfoStream
= xInRelStream
;
2789 m_pImpl
->m_aNewRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
2790 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED_STREAM
;
2793 throw lang::IllegalArgumentException(); // TODO
2795 else if ( m_pData
->m_nStorageType
== OFOPXML_STORAGE
&& aPropertyName
.equalsAscii( "RelationsInfo" ) )
2797 if ( aValue
>>= m_pImpl
->m_aNewRelInfo
)
2801 throw lang::IllegalArgumentException(); // TODO
2803 else if ( aPropertyName
.equalsAscii( "Size" ) )
2804 throw beans::PropertyVetoException(); // TODO
2805 else if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
2806 && ( aPropertyName
.equalsAscii( "IsEncrypted" ) || aPropertyName
.equalsAscii( "Encrypted" ) ) )
2807 throw beans::PropertyVetoException(); // TODO
2809 throw beans::UnknownPropertyException(); // TODO
2811 m_pImpl
->m_bHasDataToFlush
= sal_True
;
2812 ModifyParentUnlockMutex_Impl( aGuard
);
2816 //-----------------------------------------------
2817 uno::Any SAL_CALL
OWriteStream::getPropertyValue( const ::rtl::OUString
& aProp
)
2818 throw ( beans::UnknownPropertyException
,
2819 lang::WrappedTargetException
,
2820 uno::RuntimeException
)
2822 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2825 throw lang::DisposedException();
2827 if ( aProp
.equalsAscii( "RelId" ) )
2829 return uno::makeAny( m_pImpl
->GetNewRelId() );
2832 ::rtl::OUString aPropertyName
;
2833 if ( aProp
.equalsAscii( "IsEncrypted" ) )
2834 aPropertyName
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Encrypted" ) );
2836 aPropertyName
= aProp
;
2838 if ( ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
|| m_pData
->m_nStorageType
== OFOPXML_STORAGE
)
2839 && aPropertyName
.equalsAscii( "MediaType" )
2840 || m_pData
->m_nStorageType
== PACKAGE_STORAGE
&& aPropertyName
.equalsAscii( "Encrypted" )
2841 || aPropertyName
.equalsAscii( "Compressed" ) )
2843 m_pImpl
->GetStreamProperties();
2845 for ( sal_Int32 nInd
= 0; nInd
< m_pImpl
->m_aProps
.getLength(); nInd
++ )
2847 if ( aPropertyName
.equals( m_pImpl
->m_aProps
[nInd
].Name
) )
2848 return m_pImpl
->m_aProps
[nInd
].Value
;
2851 else if ( m_pData
->m_nStorageType
== PACKAGE_STORAGE
2852 && aPropertyName
.equalsAscii( "UseCommonStoragePasswordEncryption" ) )
2853 return uno::makeAny( m_pImpl
->m_bUseCommonPass
);
2854 else if ( aPropertyName
.equalsAscii( "Size" ) )
2856 CheckInitOnDemand();
2858 if ( !m_xSeekable
.is() )
2859 throw uno::RuntimeException();
2861 return uno::makeAny( (sal_Int32
)m_xSeekable
->getLength() );
2864 throw beans::UnknownPropertyException(); // TODO
2868 //-----------------------------------------------
2869 void SAL_CALL
OWriteStream::addPropertyChangeListener(
2870 const ::rtl::OUString
& /*aPropertyName*/,
2871 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/ )
2872 throw ( beans::UnknownPropertyException
,
2873 lang::WrappedTargetException
,
2874 uno::RuntimeException
)
2876 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2879 throw lang::DisposedException();
2885 //-----------------------------------------------
2886 void SAL_CALL
OWriteStream::removePropertyChangeListener(
2887 const ::rtl::OUString
& /*aPropertyName*/,
2888 const uno::Reference
< beans::XPropertyChangeListener
>& /*aListener*/ )
2889 throw ( beans::UnknownPropertyException
,
2890 lang::WrappedTargetException
,
2891 uno::RuntimeException
)
2893 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2896 throw lang::DisposedException();
2902 //-----------------------------------------------
2903 void SAL_CALL
OWriteStream::addVetoableChangeListener(
2904 const ::rtl::OUString
& /*PropertyName*/,
2905 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
2906 throw ( beans::UnknownPropertyException
,
2907 lang::WrappedTargetException
,
2908 uno::RuntimeException
)
2910 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2913 throw lang::DisposedException();
2919 //-----------------------------------------------
2920 void SAL_CALL
OWriteStream::removeVetoableChangeListener(
2921 const ::rtl::OUString
& /*PropertyName*/,
2922 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
2923 throw ( beans::UnknownPropertyException
,
2924 lang::WrappedTargetException
,
2925 uno::RuntimeException
)
2927 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
2930 throw lang::DisposedException();
2935 //____________________________________________________________________________________________________
2936 // XTransactedObject
2937 //____________________________________________________________________________________________________
2939 //-----------------------------------------------
2940 void OWriteStream::BroadcastTransaction( sal_Int8 nMessage
)
2948 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
2950 throw lang::DisposedException();
2952 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
2954 ::cppu::OInterfaceContainerHelper
* pContainer
=
2955 m_pData
->m_aListenersContainer
.getContainer(
2956 ::getCppuType( ( const uno::Reference
< embed::XTransactionListener
>*) NULL
) );
2959 ::cppu::OInterfaceIteratorHelper
pIterator( *pContainer
);
2960 while ( pIterator
.hasMoreElements( ) )
2962 OSL_ENSURE( nMessage
>= 1 && nMessage
<= 4, "Wrong internal notification code is used!\n" );
2966 case STOR_MESS_PRECOMMIT
:
2967 ( ( embed::XTransactionListener
* )pIterator
.next( ) )->preCommit( aSource
);
2969 case STOR_MESS_COMMITED
:
2970 ( ( embed::XTransactionListener
* )pIterator
.next( ) )->commited( aSource
);
2972 case STOR_MESS_PREREVERT
:
2973 ( ( embed::XTransactionListener
* )pIterator
.next( ) )->preRevert( aSource
);
2975 case STOR_MESS_REVERTED
:
2976 ( ( embed::XTransactionListener
* )pIterator
.next( ) )->reverted( aSource
);
2982 //-----------------------------------------------
2983 void SAL_CALL
OWriteStream::commit()
2984 throw ( io::IOException
,
2985 embed::StorageWrappedTargetException
,
2986 uno::RuntimeException
)
2988 RTL_LOGFILE_CONTEXT( aLog
, "package (mv76033) OWriteStream::commit" );
2991 throw lang::DisposedException();
2993 if ( !m_bTransacted
)
2994 throw uno::RuntimeException();
2997 BroadcastTransaction( STOR_MESS_PRECOMMIT
);
2999 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3002 throw lang::DisposedException();
3006 // when the storage is commited the parent is modified
3007 ModifyParentUnlockMutex_Impl( aGuard
);
3009 catch( io::IOException
& )
3013 catch( embed::StorageWrappedTargetException
& )
3017 catch( uno::RuntimeException
& )
3021 catch( uno::Exception
& )
3023 uno::Any
aCaught( ::cppu::getCaughtException() );
3024 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Problems on commit!" ),
3025 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >( this ) ),
3029 BroadcastTransaction( STOR_MESS_COMMITED
);
3032 //-----------------------------------------------
3033 void SAL_CALL
OWriteStream::revert()
3034 throw ( io::IOException
,
3035 embed::StorageWrappedTargetException
,
3036 uno::RuntimeException
)
3038 RTL_LOGFILE_CONTEXT( aLog
, "package (mv76033) OWriteStream::revert" );
3040 // the method removes all the changes done after last commit
3043 throw lang::DisposedException();
3045 if ( !m_bTransacted
)
3046 throw uno::RuntimeException();
3048 BroadcastTransaction( STOR_MESS_PREREVERT
);
3050 ::osl::ResettableMutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3053 throw lang::DisposedException();
3058 catch( io::IOException
& )
3062 catch( embed::StorageWrappedTargetException
& )
3066 catch( uno::RuntimeException
& )
3070 catch( uno::Exception
& )
3072 uno::Any
aCaught( ::cppu::getCaughtException() );
3073 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Problems on revert!" ),
3074 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >( this ) ),
3080 BroadcastTransaction( STOR_MESS_REVERTED
);
3083 //____________________________________________________________________________________________________
3084 // XTransactionBroadcaster
3085 //____________________________________________________________________________________________________
3087 //-----------------------------------------------
3088 void SAL_CALL
OWriteStream::addTransactionListener( const uno::Reference
< embed::XTransactionListener
>& aListener
)
3089 throw ( uno::RuntimeException
)
3091 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3094 throw lang::DisposedException();
3096 if ( !m_bTransacted
)
3097 throw uno::RuntimeException();
3099 m_pData
->m_aListenersContainer
.addInterface( ::getCppuType((const uno::Reference
< embed::XTransactionListener
>*)0),
3103 //-----------------------------------------------
3104 void SAL_CALL
OWriteStream::removeTransactionListener( const uno::Reference
< embed::XTransactionListener
>& aListener
)
3105 throw ( uno::RuntimeException
)
3107 ::osl::MutexGuard
aGuard( m_pData
->m_rSharedMutexRef
->GetMutex() );
3110 throw lang::DisposedException();
3112 if ( !m_bTransacted
)
3113 throw uno::RuntimeException();
3115 m_pData
->m_aListenersContainer
.removeInterface( ::getCppuType((const uno::Reference
< embed::XTransactionListener
>*)0),