1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_comphelper.hxx"
26 #include <osl/diagnose.h>
27 #include <com/sun/star/beans/PropertyAttribute.hpp>
28 #include <com/sun/star/io/XAsyncOutputMonitor.hpp>
29 #include <com/sun/star/embed/UseBackupException.hpp>
30
31 #include <comphelper/otransactedfilestream.hxx>
32 #include <comphelper/storagehelper.hxx>
33 #include <cppuhelper/implbase1.hxx>
34
35 using namespace ::com::sun::star;
36
37 namespace comphelper
38 {
39
40 // ========================================================================
41 class OTransactionHelper : public ::cppu::WeakImplHelper1 < embed::XTransactedObject >
42 {
43 OTruncatedTransactedFileStream* m_pFileStream;
44 uno::Reference< io::XStream > m_xStreamHolder;
45
46 public:
OTransactionHelper(OTruncatedTransactedFileStream * pStream)47 OTransactionHelper( OTruncatedTransactedFileStream* pStream )
48 : m_pFileStream( pStream )
49 {
50 m_xStreamHolder = static_cast< io::XStream* >( pStream );
51 if ( !m_xStreamHolder.is() )
52 throw uno::RuntimeException();
53 }
54
55 virtual void SAL_CALL commit( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException);
56 virtual void SAL_CALL revert( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException);
57 };
58
59 // ------------------------------------------------------------------------
commit()60 void SAL_CALL OTransactionHelper::commit( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException)
61 {
62 m_pFileStream->Commit_Impl();
63 }
64
65 // ------------------------------------------------------------------------
revert()66 void SAL_CALL OTransactionHelper::revert( ) throw (io::IOException, lang::WrappedTargetException, uno::RuntimeException)
67 {
68 m_pFileStream->Revert_Impl();
69 }
70
71 // ========================================================================
72 struct TTFileStreamData_Impl
73 {
74 uno::Reference< ucb::XSimpleFileAccess > m_xFileAccess;
75 sal_Bool m_bDelete;
76 ::rtl::OUString m_aURL;
77
78 // the streams below are not visible from outside so there is no need to remember position
79
80 // original stream related members
81 uno::Reference< io::XStream > m_xOrigStream;
82 uno::Reference< io::XTruncate > m_xOrigTruncate;
83 uno::Reference< io::XSeekable > m_xOrigSeekable;
84 uno::Reference< io::XInputStream > m_xOrigInStream;
85 uno::Reference< io::XOutputStream > m_xOrigOutStream;
86
87 // temporary stream related members
88 uno::Reference< io::XStream > m_xTempStream;
89 uno::Reference< io::XTruncate > m_xTempTruncate;
90 uno::Reference< io::XSeekable > m_xTempSeekable;
91 uno::Reference< io::XInputStream > m_xTempInStream;
92 uno::Reference< io::XOutputStream > m_xTempOutStream;
93
94 sal_Bool m_bInOpen;
95 sal_Bool m_bOutOpen;
96
97 sal_Bool m_bTransacted;
98
99
TTFileStreamData_Implcomphelper::TTFileStreamData_Impl100 TTFileStreamData_Impl(
101 const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess,
102 sal_Bool bDelete,
103 const ::rtl::OUString& aURL,
104 const uno::Reference< io::XStream >& xOrigStream,
105 const uno::Reference< io::XTruncate >& xOrigTruncate,
106 const uno::Reference< io::XSeekable >& xOrigSeekable,
107 const uno::Reference< io::XInputStream >& xOrigInStream,
108 const uno::Reference< io::XOutputStream >& xOrigOutStream,
109 const uno::Reference< io::XStream >& xTempStream,
110 const uno::Reference< io::XTruncate >& xTempTruncate,
111 const uno::Reference< io::XSeekable >& xTempSeekable,
112 const uno::Reference< io::XInputStream >& xTempInStream,
113 const uno::Reference< io::XOutputStream >& xTempOutStream )
114 : m_xFileAccess( xFileAccess )
115 , m_bDelete( bDelete )
116 , m_aURL( aURL )
117 , m_xOrigStream( xOrigStream )
118 , m_xOrigTruncate( xOrigTruncate )
119 , m_xOrigSeekable( xOrigSeekable )
120 , m_xOrigInStream( xOrigInStream )
121 , m_xOrigOutStream( xOrigOutStream )
122 , m_xTempStream( xTempStream )
123 , m_xTempTruncate( xTempTruncate )
124 , m_xTempSeekable( xTempSeekable )
125 , m_xTempInStream( xTempInStream )
126 , m_xTempOutStream( xTempOutStream )
127 , m_bInOpen( sal_False )
128 , m_bOutOpen( sal_False )
129 , m_bTransacted( sal_True )
130 {}
131
NoTransactioncomphelper::TTFileStreamData_Impl132 void NoTransaction()
133 {
134 m_bDelete = sal_False;
135 m_bTransacted = sal_False;
136 m_xTempStream = uno::Reference< io::XStream >();
137 m_xTempTruncate = uno::Reference< io::XTruncate >();
138 m_xTempSeekable = uno::Reference< io::XSeekable >();
139 m_xTempInStream = uno::Reference< io::XInputStream >();
140 m_xTempOutStream = uno::Reference< io::XOutputStream >();
141 }
142
FreeOriginalcomphelper::TTFileStreamData_Impl143 void FreeOriginal()
144 {
145 m_bDelete = sal_False;
146 m_bTransacted = sal_False;
147
148 m_xOrigStream = m_xTempStream;
149 m_xTempStream = uno::Reference< io::XStream >();
150
151 m_xOrigTruncate = m_xTempTruncate;
152 m_xTempTruncate = uno::Reference< io::XTruncate >();
153
154 m_xOrigSeekable = m_xTempSeekable;
155 m_xTempSeekable = uno::Reference< io::XSeekable >();
156
157 m_xOrigInStream = m_xTempInStream;
158 m_xTempInStream = uno::Reference< io::XInputStream >();
159
160 m_xOrigOutStream = m_xTempOutStream;
161 m_xTempOutStream = uno::Reference< io::XOutputStream >();
162 }
163 };
164
165 // ========================================================================
166 // ------------------------------------------------------------------------
OTruncatedTransactedFileStream(const::rtl::OUString & aURL,const uno::Reference<lang::XMultiServiceFactory> & xFactory)167 OTruncatedTransactedFileStream::OTruncatedTransactedFileStream(
168 const ::rtl::OUString& aURL,
169 const uno::Reference< lang::XMultiServiceFactory >& xFactory )
170 : m_pStreamData( NULL )
171 {
172 uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
173 xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
174 uno::UNO_QUERY_THROW );
175
176 CommonInit_Impl( aURL, xSimpleFileAccess, xFactory, sal_False );
177 }
178
179 // ------------------------------------------------------------------------
OTruncatedTransactedFileStream(const::rtl::OUString & aURL,const uno::Reference<ucb::XSimpleFileAccess> & xFileAccess,const uno::Reference<lang::XMultiServiceFactory> & xFactory)180 OTruncatedTransactedFileStream::OTruncatedTransactedFileStream(
181 const ::rtl::OUString& aURL,
182 const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess,
183 const uno::Reference< lang::XMultiServiceFactory >& xFactory )
184 : m_pStreamData( NULL )
185 {
186 CommonInit_Impl( aURL, xFileAccess, xFactory, sal_False );
187 }
188
189 // ------------------------------------------------------------------------
OTruncatedTransactedFileStream(const::rtl::OUString & aURL,const uno::Reference<ucb::XSimpleFileAccess> & xFileAccess,const uno::Reference<lang::XMultiServiceFactory> & xFactory,sal_Bool bDeleteIfNotCommited)190 OTruncatedTransactedFileStream::OTruncatedTransactedFileStream(
191 const ::rtl::OUString& aURL,
192 const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess,
193 const uno::Reference< lang::XMultiServiceFactory >& xFactory,
194 sal_Bool bDeleteIfNotCommited )
195 : m_pStreamData( NULL )
196 {
197 CommonInit_Impl( aURL, xFileAccess, xFactory, sal_True );
198 if ( m_pStreamData )
199 m_pStreamData->m_bDelete = bDeleteIfNotCommited;
200 }
201
202 // ------------------------------------------------------------------------
~OTruncatedTransactedFileStream()203 OTruncatedTransactedFileStream::~OTruncatedTransactedFileStream()
204 {
205 CloseAll_Impl();
206 }
207
208 // ------------------------------------------------------------------------
CloseAll_Impl()209 void OTruncatedTransactedFileStream::CloseAll_Impl()
210 {
211 ::osl::MutexGuard aGuard( m_aMutex );
212
213 if ( m_pStreamData )
214 {
215 sal_Bool bDelete = m_pStreamData->m_bDelete;
216 ::rtl::OUString aURL = m_pStreamData->m_aURL;
217 uno::Reference< ucb::XSimpleFileAccess > xFileAccess = m_pStreamData->m_xFileAccess;
218
219 delete m_pStreamData;
220 m_pStreamData = NULL;
221
222 if ( bDelete && xFileAccess.is() && !aURL.isEmpty() )
223 {
224 // delete the file
225 try
226 {
227 xFileAccess->kill( aURL );
228 } catch( uno::Exception& )
229 {
230 OSL_ENSURE( sal_False, "Could not remove the file!" );
231 }
232 }
233 }
234 }
235
236 // ------------------------------------------------------------------------
CommonInit_Impl(const::rtl::OUString & aURL,const uno::Reference<ucb::XSimpleFileAccess> & xFileAccess,const uno::Reference<lang::XMultiServiceFactory> & xFactory,sal_Bool bDeleteOptionIsProvided)237 void OTruncatedTransactedFileStream::CommonInit_Impl(
238 const ::rtl::OUString& aURL,
239 const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess,
240 const uno::Reference< lang::XMultiServiceFactory >& xFactory,
241 sal_Bool bDeleteOptionIsProvided )
242 {
243 sal_Bool bDelete = sal_False;
244 if ( !bDeleteOptionIsProvided )
245 bDelete = !xFileAccess->exists( aURL );
246
247 uno::Reference< io::XStream > xOrigStream = xFileAccess->openFileReadWrite( aURL );
248 uno::Reference< io::XTruncate > xOrigTruncate( xOrigStream, uno::UNO_QUERY_THROW );
249 uno::Reference< io::XSeekable > xOrigSeekable( xOrigStream, uno::UNO_QUERY_THROW );
250 uno::Reference< io::XInputStream > xOrigInStream = xOrigStream->getInputStream();
251 uno::Reference< io::XOutputStream > xOrigOutStream = xOrigStream->getOutputStream();
252 if ( !xOrigInStream.is() || !xOrigOutStream.is() )
253 throw uno::RuntimeException();
254
255 // temporary stream related members
256 uno::Reference< io::XStream > xTempStream( xFactory->createInstance(
257 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
258 uno::UNO_QUERY_THROW );
259 uno::Reference< io::XTruncate > xTempTruncate( xTempStream, uno::UNO_QUERY_THROW );
260 uno::Reference< io::XSeekable > xTempSeekable( xTempStream, uno::UNO_QUERY_THROW );
261 uno::Reference< io::XInputStream > xTempInStream = xTempStream->getInputStream();
262 uno::Reference< io::XOutputStream > xTempOutStream = xTempStream->getOutputStream();
263 if ( !xTempInStream.is() || !xTempOutStream.is() )
264 throw uno::RuntimeException();
265
266 m_pStreamData = new TTFileStreamData_Impl( xFileAccess, bDelete, aURL,
267 xOrigStream, xOrigTruncate, xOrigSeekable, xOrigInStream, xOrigOutStream,
268 xTempStream, xTempTruncate, xTempSeekable, xTempInStream, xTempOutStream );
269 }
270
271 // ------------------------------------------------------------------------
Commit_Impl()272 void OTruncatedTransactedFileStream::Commit_Impl()
273 {
274 ::osl::MutexGuard aGuard( m_aMutex );
275
276 if ( !m_pStreamData )
277 throw io::NotConnectedException();
278
279 if ( m_pStreamData->m_bTransacted )
280 {
281 sal_Int64 nPos = m_pStreamData->m_xTempSeekable->getPosition();
282 m_pStreamData->m_xTempSeekable->seek( 0 );
283
284 // after the following step fails the information might be lost, throw an exception with URL of temporary file
285 try
286 {
287 m_pStreamData->m_xOrigTruncate->truncate();
288 OStorageHelper::CopyInputToOutput( m_pStreamData->m_xTempInStream, m_pStreamData->m_xOrigOutStream );
289 m_pStreamData->m_xOrigOutStream->flush();
290
291 // in case the stream is based on a file it will implement the following interface
292 // the call should be used to be sure that the contents are written to the file system
293 uno::Reference< io::XAsyncOutputMonitor > asyncOutputMonitor( m_pStreamData->m_xOrigOutStream, uno::UNO_QUERY );
294 if ( asyncOutputMonitor.is() )
295 asyncOutputMonitor->waitForCompletion();
296 }
297 catch( uno::Exception& )
298 {
299 ::rtl::OUString aTempURL;
300 try {
301 uno::Reference< beans::XPropertySet > xTempFile( m_pStreamData->m_xTempStream, uno::UNO_QUERY_THROW );
302 uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
303 aUrl >>= aTempURL;
304 xTempFile->setPropertyValue( ::rtl::OUString::createFromAscii( "RemoveFile" ),
305 uno::makeAny( sal_False ) );
306
307 m_pStreamData->m_xTempSeekable->seek( nPos );
308 }
309 catch( uno::Exception& )
310 {
311 OSL_ENSURE( sal_False, "These calls are pretty simple, they should not fail!\n" );
312 }
313
314 m_pStreamData->FreeOriginal();
315
316 ::rtl::OUString aErrTxt( RTL_CONSTASCII_USTRINGPARAM ( "Writing file failed!" ) );
317 embed::UseBackupException aException( aErrTxt, uno::Reference< uno::XInterface >(), aTempURL );
318 throw lang::WrappedTargetException( aErrTxt,
319 static_cast < OWeakObject * > ( this ),
320 uno::makeAny ( aException ) );
321 }
322
323 m_pStreamData->m_xOrigSeekable->seek( nPos );
324 m_pStreamData->NoTransaction();
325 }
326 else
327 throw io::NotConnectedException();
328 }
329
330 // ------------------------------------------------------------------------
Revert_Impl()331 void OTruncatedTransactedFileStream::Revert_Impl()
332 {
333 ::osl::MutexGuard aGuard( m_aMutex );
334
335 if ( !m_pStreamData )
336 throw io::NotConnectedException();
337
338 if ( m_pStreamData->m_bTransacted )
339 m_pStreamData->m_xTempTruncate->truncate();
340 else
341 throw io::NotConnectedException();
342 }
343
344 // com::sun::star::io::XStream
345 // ------------------------------------------------------------------------
getInputStream()346 uno::Reference< io::XInputStream > SAL_CALL OTruncatedTransactedFileStream::getInputStream( )
347 throw (uno::RuntimeException)
348 {
349 ::osl::MutexGuard aGuard( m_aMutex );
350
351 if ( m_pStreamData )
352 m_pStreamData->m_bInOpen = sal_True;
353 return static_cast< io::XInputStream* >( this );
354 }
355
356
357 // ------------------------------------------------------------------------
getOutputStream()358 uno::Reference< io::XOutputStream > SAL_CALL OTruncatedTransactedFileStream::getOutputStream( )
359 throw (uno::RuntimeException)
360 {
361 ::osl::MutexGuard aGuard( m_aMutex );
362
363 if ( m_pStreamData )
364 m_pStreamData->m_bOutOpen = sal_True;
365 return static_cast< io::XOutputStream* >( this );
366 }
367
368
369
370 // com::sun::star::io::XInputStream
371 // ------------------------------------------------------------------------
readBytes(uno::Sequence<::sal_Int8> & aData,::sal_Int32 nBytesToRead)372 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead )
373 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
374 {
375 ::osl::MutexGuard aGuard( m_aMutex );
376
377 if ( !m_pStreamData )
378 throw io::NotConnectedException();
379
380 if ( m_pStreamData->m_bTransacted )
381 {
382 // temporary stream data should be provided
383 if ( !m_pStreamData->m_xTempInStream.is() )
384 throw uno::RuntimeException();
385
386 return m_pStreamData->m_xTempInStream->readBytes( aData, nBytesToRead );
387 }
388 else
389 {
390 // the original stream data should be provided
391 if ( !m_pStreamData->m_xOrigInStream.is() )
392 throw uno::RuntimeException();
393
394 return m_pStreamData->m_xOrigInStream->readBytes( aData, nBytesToRead );
395 }
396 }
397
398
399 // ------------------------------------------------------------------------
readSomeBytes(uno::Sequence<::sal_Int8> & aData,::sal_Int32 nMaxBytesToRead)400 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead )
401 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
402 {
403 ::osl::MutexGuard aGuard( m_aMutex );
404
405 if ( !m_pStreamData )
406 throw io::NotConnectedException();
407
408 if ( m_pStreamData->m_bTransacted )
409 {
410 // temporary stream data should be provided
411 if ( !m_pStreamData->m_xTempInStream.is() )
412 throw uno::RuntimeException();
413
414 return m_pStreamData->m_xTempInStream->readSomeBytes( aData, nMaxBytesToRead );
415 }
416 else
417 {
418 // the original stream data should be provided
419 if ( !m_pStreamData->m_xOrigInStream.is() )
420 throw uno::RuntimeException();
421
422 return m_pStreamData->m_xOrigInStream->readSomeBytes( aData, nMaxBytesToRead );
423 }
424 }
425
426 // ------------------------------------------------------------------------
skipBytes(::sal_Int32 nBytesToSkip)427 void SAL_CALL OTruncatedTransactedFileStream::skipBytes( ::sal_Int32 nBytesToSkip )
428 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
429 {
430 ::osl::MutexGuard aGuard( m_aMutex );
431
432 if ( !m_pStreamData )
433 throw io::NotConnectedException();
434
435 if ( m_pStreamData->m_bTransacted )
436 {
437 // temporary stream data should be provided
438 if ( !m_pStreamData->m_xTempInStream.is() )
439 throw uno::RuntimeException();
440
441 m_pStreamData->m_xTempInStream->skipBytes( nBytesToSkip );
442 }
443 else
444 {
445 // the original stream data should be provided
446 if ( !m_pStreamData->m_xOrigInStream.is() )
447 throw uno::RuntimeException();
448
449 m_pStreamData->m_xOrigInStream->skipBytes( nBytesToSkip );
450 }
451 }
452
453
454 // ------------------------------------------------------------------------
available()455 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::available( )
456 throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
457 {
458 ::osl::MutexGuard aGuard( m_aMutex );
459
460 if ( !m_pStreamData )
461 throw io::NotConnectedException();
462
463 if ( m_pStreamData->m_bTransacted )
464 {
465 // temporary stream data should be provided
466 if ( !m_pStreamData->m_xTempInStream.is() )
467 throw uno::RuntimeException();
468
469 return m_pStreamData->m_xTempInStream->available();
470 }
471 else
472 {
473 // the original stream data should be provided
474 if ( !m_pStreamData->m_xOrigInStream.is() )
475 throw uno::RuntimeException();
476
477 return m_pStreamData->m_xOrigInStream->available();
478 }
479 }
480
481
482 // ------------------------------------------------------------------------
closeInput()483 void SAL_CALL OTruncatedTransactedFileStream::closeInput()
484 throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
485 {
486 ::osl::MutexGuard aGuard( m_aMutex );
487
488 if ( !m_pStreamData )
489 throw io::NotConnectedException();
490
491 m_pStreamData->m_bInOpen = sal_False;
492 if ( !m_pStreamData->m_bOutOpen )
493 CloseAll_Impl();
494 }
495
496
497
498 // com::sun::star::io::XOutputStream
499 // ------------------------------------------------------------------------
writeBytes(const uno::Sequence<::sal_Int8> & aData)500 void SAL_CALL OTruncatedTransactedFileStream::writeBytes( const uno::Sequence< ::sal_Int8 >& aData )
501 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
502 {
503 ::osl::MutexGuard aGuard( m_aMutex );
504
505 if ( !m_pStreamData )
506 throw io::NotConnectedException();
507
508 if ( m_pStreamData->m_bTransacted )
509 {
510 // temporary stream data should be provided
511 if ( !m_pStreamData->m_xTempOutStream.is() )
512 throw uno::RuntimeException();
513
514 m_pStreamData->m_xTempOutStream->writeBytes( aData );
515 }
516 else
517 {
518 // the original stream data should be provided
519 if ( !m_pStreamData->m_xOrigOutStream.is() )
520 throw uno::RuntimeException();
521
522 m_pStreamData->m_xOrigOutStream->writeBytes( aData );
523 }
524 }
525
526
527 // ------------------------------------------------------------------------
flush()528 void SAL_CALL OTruncatedTransactedFileStream::flush( )
529 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
530 {
531 ::osl::MutexGuard aGuard( m_aMutex );
532
533 if ( !m_pStreamData )
534 {
535 OSL_ENSURE( sal_False, "flush() call on closed stream!\n" );
536 return;
537 // in future throw exception, for now some code might call flush() on closed stream
538 // since file ucp implementation allows it
539 // throw io::NotConnectedException();
540 }
541
542 if ( m_pStreamData->m_bTransacted )
543 {
544 // temporary stream data should be provided
545 if ( !m_pStreamData->m_xTempOutStream.is() )
546 throw uno::RuntimeException();
547
548 m_pStreamData->m_xTempOutStream->flush();
549 }
550 else
551 {
552 // the original stream data should be provided
553 if ( !m_pStreamData->m_xOrigOutStream.is() )
554 throw uno::RuntimeException();
555
556 m_pStreamData->m_xOrigOutStream->flush();
557 }
558 }
559
560
561 // ------------------------------------------------------------------------
closeOutput()562 void SAL_CALL OTruncatedTransactedFileStream::closeOutput( )
563 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
564 {
565 ::osl::MutexGuard aGuard( m_aMutex );
566
567 if ( !m_pStreamData )
568 throw io::NotConnectedException();
569
570 m_pStreamData->m_bOutOpen = sal_False;
571 if ( !m_pStreamData->m_bInOpen )
572 CloseAll_Impl();
573 }
574
575
576
577 // com::sun::star::io::XTruncate
578 // ------------------------------------------------------------------------
truncate()579 void SAL_CALL OTruncatedTransactedFileStream::truncate( )
580 throw (io::IOException, uno::RuntimeException)
581 {
582 ::osl::MutexGuard aGuard( m_aMutex );
583
584 if ( !m_pStreamData )
585 throw io::NotConnectedException();
586
587 if ( m_pStreamData->m_bTransacted )
588 {
589 // temporary stream data should be provided
590 if ( !m_pStreamData->m_xTempTruncate.is() )
591 throw uno::RuntimeException();
592
593 m_pStreamData->m_xTempTruncate->truncate();
594 }
595 else
596 {
597 // the original stream data should be provided
598 if ( !m_pStreamData->m_xOrigTruncate.is() )
599 throw uno::RuntimeException();
600
601 m_pStreamData->m_xOrigTruncate->truncate();
602 }
603 }
604
605
606
607 // com::sun::star::io::XSeekable
608 // ------------------------------------------------------------------------
seek(::sal_Int64 location)609 void SAL_CALL OTruncatedTransactedFileStream::seek( ::sal_Int64 location )
610 throw (lang::IllegalArgumentException, io::IOException, uno::RuntimeException)
611 {
612 ::osl::MutexGuard aGuard( m_aMutex );
613
614 if ( !m_pStreamData )
615 throw io::NotConnectedException();
616
617 if ( m_pStreamData->m_bTransacted )
618 {
619 // temporary stream data should be provided
620 if ( !m_pStreamData->m_xTempSeekable.is() )
621 throw uno::RuntimeException();
622
623 m_pStreamData->m_xTempSeekable->seek( location );
624 }
625 else
626 {
627 // the original stream data should be provided
628 if ( !m_pStreamData->m_xOrigSeekable.is() )
629 throw uno::RuntimeException();
630
631 m_pStreamData->m_xOrigSeekable->seek( location );
632 }
633 }
634
635
636 // ------------------------------------------------------------------------
getPosition()637 ::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getPosition( )
638 throw (io::IOException, uno::RuntimeException)
639 {
640 ::osl::MutexGuard aGuard( m_aMutex );
641
642 if ( !m_pStreamData )
643 throw io::NotConnectedException();
644
645 if ( m_pStreamData->m_bTransacted )
646 {
647 // temporary stream data should be provided
648 if ( !m_pStreamData->m_xTempSeekable.is() )
649 throw uno::RuntimeException();
650
651 return m_pStreamData->m_xTempSeekable->getPosition();
652 }
653 else
654 {
655 // the original stream data should be provided
656 if ( !m_pStreamData->m_xOrigSeekable.is() )
657 throw uno::RuntimeException();
658
659 return m_pStreamData->m_xOrigSeekable->getPosition();
660 }
661 }
662
663
664 // ------------------------------------------------------------------------
getLength()665 ::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getLength( )
666 throw (io::IOException, uno::RuntimeException)
667 {
668 ::osl::MutexGuard aGuard( m_aMutex );
669
670 if ( !m_pStreamData )
671 throw io::NotConnectedException();
672
673 if ( m_pStreamData->m_bTransacted )
674 {
675 // temporary stream data should be provided
676 if ( !m_pStreamData->m_xTempSeekable.is() )
677 throw uno::RuntimeException();
678
679 return m_pStreamData->m_xTempSeekable->getLength();
680 }
681 else
682 {
683 // the original stream data should be provided
684 if ( !m_pStreamData->m_xOrigSeekable.is() )
685 throw uno::RuntimeException();
686
687 return m_pStreamData->m_xOrigSeekable->getLength();
688 }
689 }
690
691 // com::sun::star::beans::XPropertySetInfo
692 // ------------------------------------------------------------------------
getProperties()693 uno::Sequence< beans::Property > SAL_CALL OTruncatedTransactedFileStream::getProperties()
694 throw (uno::RuntimeException)
695 {
696 ::osl::MutexGuard aGuard( m_aMutex );
697
698 uno::Sequence< beans::Property > aProps( 1 );
699 aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
700 aProps[0].Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) );
701 aProps[0].Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY;
702
703 return aProps;
704 }
705
706
707 // ------------------------------------------------------------------------
getPropertyByName(const::rtl::OUString & aName)708 beans::Property SAL_CALL OTruncatedTransactedFileStream::getPropertyByName( const ::rtl::OUString& aName )
709 throw (beans::UnknownPropertyException, uno::RuntimeException)
710 {
711 ::osl::MutexGuard aGuard( m_aMutex );
712
713 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
714
715 if ( !aName.equals( aTransactionPropName ) )
716 throw beans::UnknownPropertyException();
717
718 beans::Property aProp;
719 aProp.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
720 aProp.Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) );
721 aProp.Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY;
722
723 return aProp;
724 }
725
726
727 // ------------------------------------------------------------------------
hasPropertyByName(const::rtl::OUString & Name)728 ::sal_Bool SAL_CALL OTruncatedTransactedFileStream::hasPropertyByName( const ::rtl::OUString& Name )
729 throw (uno::RuntimeException)
730 {
731 ::osl::MutexGuard aGuard( m_aMutex );
732
733 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
734 return ( Name.equals( aTransactionPropName ) );
735 }
736
737
738
739 // com::sun::star::beans::XPropertySet
740 // ------------------------------------------------------------------------
getPropertySetInfo()741 uno::Reference< beans::XPropertySetInfo > SAL_CALL OTruncatedTransactedFileStream::getPropertySetInfo()
742 throw (uno::RuntimeException)
743 {
744 ::osl::MutexGuard aGuard( m_aMutex );
745
746 return static_cast< beans::XPropertySetInfo* >( this );
747 }
748
749
750 // ------------------------------------------------------------------------
setPropertyValue(const::rtl::OUString & aPropertyName,const uno::Any &)751 void SAL_CALL OTruncatedTransactedFileStream::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& )
752 throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
753 {
754 ::osl::MutexGuard aGuard( m_aMutex );
755
756 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
757 if ( aPropertyName.equals( aTransactionPropName ) )
758 throw beans::PropertyVetoException();
759
760 throw beans::UnknownPropertyException();
761 }
762
763
764 // ------------------------------------------------------------------------
getPropertyValue(const::rtl::OUString & PropertyName)765 uno::Any SAL_CALL OTruncatedTransactedFileStream::getPropertyValue( const ::rtl::OUString& PropertyName )
766 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
767 {
768 ::osl::MutexGuard aGuard( m_aMutex );
769
770 if ( !m_pStreamData )
771 throw io::NotConnectedException();
772
773 ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
774 if ( PropertyName.equals( aTransactionPropName ) )
775 {
776 uno::Reference< embed::XTransactedObject > xObj;
777 if ( m_pStreamData->m_bTransacted )
778 xObj = static_cast< embed::XTransactedObject* >( new OTransactionHelper( this ) );
779
780 return uno::makeAny( xObj );
781 }
782
783 throw beans::UnknownPropertyException();
784 }
785
786
787 // ------------------------------------------------------------------------
addPropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)788 void SAL_CALL OTruncatedTransactedFileStream::addPropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& )
789 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
790 {
791 // not implemented
792 }
793
794
795 // ------------------------------------------------------------------------
removePropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)796 void SAL_CALL OTruncatedTransactedFileStream::removePropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& )
797 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
798 {
799 // not implemented
800 }
801
802
803 // ------------------------------------------------------------------------
addVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)804 void SAL_CALL OTruncatedTransactedFileStream::addVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& )
805 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
806 {
807 // not implemented
808 }
809
810
811 // ------------------------------------------------------------------------
removeVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)812 void SAL_CALL OTruncatedTransactedFileStream::removeVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& )
813 throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
814 {
815 // not implemented
816 }
817
818
819 } // namespace comphelper
820
821