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