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