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