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