xref: /trunk/main/comphelper/source/streaming/otransactedfilestream.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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(  );
56     virtual void SAL_CALL revert(  );
57 };
58 
59 // ------------------------------------------------------------------------
commit()60 void SAL_CALL OTransactionHelper::commit(  )
61 {
62     m_pFileStream->Commit_Impl();
63 }
64 
65 // ------------------------------------------------------------------------
revert()66 void SAL_CALL OTransactionHelper::revert(  )
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 {
348     ::osl::MutexGuard aGuard( m_aMutex );
349 
350     if ( m_pStreamData )
351         m_pStreamData->m_bInOpen = sal_True;
352     return static_cast< io::XInputStream* >( this );
353 }
354 
355 
356 // ------------------------------------------------------------------------
getOutputStream()357 uno::Reference< io::XOutputStream > SAL_CALL OTruncatedTransactedFileStream::getOutputStream(  )
358 {
359     ::osl::MutexGuard aGuard( m_aMutex );
360 
361     if ( m_pStreamData )
362         m_pStreamData->m_bOutOpen = sal_True;
363     return static_cast< io::XOutputStream* >( this );
364 }
365 
366 
367 
368 // com::sun::star::io::XInputStream
369 // ------------------------------------------------------------------------
readBytes(uno::Sequence<::sal_Int8> & aData,::sal_Int32 nBytesToRead)370 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead )
371 {
372     ::osl::MutexGuard aGuard( m_aMutex );
373 
374     if ( !m_pStreamData )
375         throw io::NotConnectedException();
376 
377     if ( m_pStreamData->m_bTransacted )
378     {
379         // temporary stream data should be provided
380         if ( !m_pStreamData->m_xTempInStream.is() )
381             throw uno::RuntimeException();
382 
383         return m_pStreamData->m_xTempInStream->readBytes( aData, nBytesToRead );
384     }
385     else
386     {
387         // the original stream data should be provided
388         if ( !m_pStreamData->m_xOrigInStream.is() )
389             throw uno::RuntimeException();
390 
391         return m_pStreamData->m_xOrigInStream->readBytes( aData, nBytesToRead );
392     }
393 }
394 
395 
396 // ------------------------------------------------------------------------
readSomeBytes(uno::Sequence<::sal_Int8> & aData,::sal_Int32 nMaxBytesToRead)397 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead )
398 {
399     ::osl::MutexGuard aGuard( m_aMutex );
400 
401     if ( !m_pStreamData )
402         throw io::NotConnectedException();
403 
404     if ( m_pStreamData->m_bTransacted )
405     {
406         // temporary stream data should be provided
407         if ( !m_pStreamData->m_xTempInStream.is() )
408             throw uno::RuntimeException();
409 
410         return m_pStreamData->m_xTempInStream->readSomeBytes( aData, nMaxBytesToRead );
411     }
412     else
413     {
414         // the original stream data should be provided
415         if ( !m_pStreamData->m_xOrigInStream.is() )
416             throw uno::RuntimeException();
417 
418         return m_pStreamData->m_xOrigInStream->readSomeBytes( aData, nMaxBytesToRead );
419     }
420 }
421 
422 // ------------------------------------------------------------------------
skipBytes(::sal_Int32 nBytesToSkip)423 void SAL_CALL OTruncatedTransactedFileStream::skipBytes( ::sal_Int32 nBytesToSkip )
424 {
425     ::osl::MutexGuard aGuard( m_aMutex );
426 
427     if ( !m_pStreamData )
428         throw io::NotConnectedException();
429 
430     if ( m_pStreamData->m_bTransacted )
431     {
432         // temporary stream data should be provided
433         if ( !m_pStreamData->m_xTempInStream.is() )
434             throw uno::RuntimeException();
435 
436         m_pStreamData->m_xTempInStream->skipBytes( nBytesToSkip );
437     }
438     else
439     {
440         // the original stream data should be provided
441         if ( !m_pStreamData->m_xOrigInStream.is() )
442             throw uno::RuntimeException();
443 
444         m_pStreamData->m_xOrigInStream->skipBytes( nBytesToSkip );
445     }
446 }
447 
448 
449 // ------------------------------------------------------------------------
available()450 ::sal_Int32 SAL_CALL OTruncatedTransactedFileStream::available(  )
451 {
452     ::osl::MutexGuard aGuard( m_aMutex );
453 
454     if ( !m_pStreamData )
455         throw io::NotConnectedException();
456 
457     if ( m_pStreamData->m_bTransacted )
458     {
459         // temporary stream data should be provided
460         if ( !m_pStreamData->m_xTempInStream.is() )
461             throw uno::RuntimeException();
462 
463         return m_pStreamData->m_xTempInStream->available();
464     }
465     else
466     {
467         // the original stream data should be provided
468         if ( !m_pStreamData->m_xOrigInStream.is() )
469             throw uno::RuntimeException();
470 
471         return m_pStreamData->m_xOrigInStream->available();
472     }
473 }
474 
475 
476 // ------------------------------------------------------------------------
closeInput()477 void SAL_CALL OTruncatedTransactedFileStream::closeInput()
478 {
479     ::osl::MutexGuard aGuard( m_aMutex );
480 
481     if ( !m_pStreamData )
482         throw io::NotConnectedException();
483 
484     m_pStreamData->m_bInOpen = sal_False;
485     if ( !m_pStreamData->m_bOutOpen )
486         CloseAll_Impl();
487 }
488 
489 
490 
491 // com::sun::star::io::XOutputStream
492 // ------------------------------------------------------------------------
writeBytes(const uno::Sequence<::sal_Int8> & aData)493 void SAL_CALL OTruncatedTransactedFileStream::writeBytes( const uno::Sequence< ::sal_Int8 >& aData )
494 {
495     ::osl::MutexGuard aGuard( m_aMutex );
496 
497     if ( !m_pStreamData )
498         throw io::NotConnectedException();
499 
500     if ( m_pStreamData->m_bTransacted )
501     {
502         // temporary stream data should be provided
503         if ( !m_pStreamData->m_xTempOutStream.is() )
504             throw uno::RuntimeException();
505 
506         m_pStreamData->m_xTempOutStream->writeBytes( aData );
507     }
508     else
509     {
510         // the original stream data should be provided
511         if ( !m_pStreamData->m_xOrigOutStream.is() )
512             throw uno::RuntimeException();
513 
514         m_pStreamData->m_xOrigOutStream->writeBytes( aData );
515     }
516 }
517 
518 
519 // ------------------------------------------------------------------------
flush()520 void SAL_CALL OTruncatedTransactedFileStream::flush(  )
521 {
522     ::osl::MutexGuard aGuard( m_aMutex );
523 
524     if ( !m_pStreamData )
525     {
526         OSL_ENSURE( sal_False, "flush() call on closed stream!\n" );
527         return;
528         // in future throw exception, for now some code might call flush() on closed stream
529         // since file ucp implementation allows it
530         // throw io::NotConnectedException();
531     }
532 
533     if ( m_pStreamData->m_bTransacted )
534     {
535         // temporary stream data should be provided
536         if ( !m_pStreamData->m_xTempOutStream.is() )
537             throw uno::RuntimeException();
538 
539         m_pStreamData->m_xTempOutStream->flush();
540     }
541     else
542     {
543         // the original stream data should be provided
544         if ( !m_pStreamData->m_xOrigOutStream.is() )
545             throw uno::RuntimeException();
546 
547         m_pStreamData->m_xOrigOutStream->flush();
548     }
549 }
550 
551 
552 // ------------------------------------------------------------------------
closeOutput()553 void SAL_CALL OTruncatedTransactedFileStream::closeOutput(  )
554 {
555     ::osl::MutexGuard aGuard( m_aMutex );
556 
557     if ( !m_pStreamData )
558         throw io::NotConnectedException();
559 
560     m_pStreamData->m_bOutOpen = sal_False;
561     if ( !m_pStreamData->m_bInOpen )
562         CloseAll_Impl();
563 }
564 
565 
566 
567 // com::sun::star::io::XTruncate
568 // ------------------------------------------------------------------------
truncate()569 void SAL_CALL OTruncatedTransactedFileStream::truncate(  )
570 {
571     ::osl::MutexGuard aGuard( m_aMutex );
572 
573     if ( !m_pStreamData )
574         throw io::NotConnectedException();
575 
576     if ( m_pStreamData->m_bTransacted )
577     {
578         // temporary stream data should be provided
579         if ( !m_pStreamData->m_xTempTruncate.is() )
580             throw uno::RuntimeException();
581 
582         m_pStreamData->m_xTempTruncate->truncate();
583     }
584     else
585     {
586         // the original stream data should be provided
587         if ( !m_pStreamData->m_xOrigTruncate.is() )
588             throw uno::RuntimeException();
589 
590         m_pStreamData->m_xOrigTruncate->truncate();
591     }
592 }
593 
594 
595 
596 // com::sun::star::io::XSeekable
597 // ------------------------------------------------------------------------
seek(::sal_Int64 location)598 void SAL_CALL OTruncatedTransactedFileStream::seek( ::sal_Int64 location )
599 {
600     ::osl::MutexGuard aGuard( m_aMutex );
601 
602     if ( !m_pStreamData )
603         throw io::NotConnectedException();
604 
605     if ( m_pStreamData->m_bTransacted )
606     {
607         // temporary stream data should be provided
608         if ( !m_pStreamData->m_xTempSeekable.is() )
609             throw uno::RuntimeException();
610 
611         m_pStreamData->m_xTempSeekable->seek( location );
612     }
613     else
614     {
615         // the original stream data should be provided
616         if ( !m_pStreamData->m_xOrigSeekable.is() )
617             throw uno::RuntimeException();
618 
619         m_pStreamData->m_xOrigSeekable->seek( location );
620     }
621 }
622 
623 
624 // ------------------------------------------------------------------------
getPosition()625 ::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getPosition(  )
626 {
627     ::osl::MutexGuard aGuard( m_aMutex );
628 
629     if ( !m_pStreamData )
630         throw io::NotConnectedException();
631 
632     if ( m_pStreamData->m_bTransacted )
633     {
634         // temporary stream data should be provided
635         if ( !m_pStreamData->m_xTempSeekable.is() )
636             throw uno::RuntimeException();
637 
638         return m_pStreamData->m_xTempSeekable->getPosition();
639     }
640     else
641     {
642         // the original stream data should be provided
643         if ( !m_pStreamData->m_xOrigSeekable.is() )
644             throw uno::RuntimeException();
645 
646         return m_pStreamData->m_xOrigSeekable->getPosition();
647     }
648 }
649 
650 
651 // ------------------------------------------------------------------------
getLength()652 ::sal_Int64 SAL_CALL OTruncatedTransactedFileStream::getLength(  )
653 {
654     ::osl::MutexGuard aGuard( m_aMutex );
655 
656     if ( !m_pStreamData )
657         throw io::NotConnectedException();
658 
659     if ( m_pStreamData->m_bTransacted )
660     {
661         // temporary stream data should be provided
662         if ( !m_pStreamData->m_xTempSeekable.is() )
663             throw uno::RuntimeException();
664 
665         return m_pStreamData->m_xTempSeekable->getLength();
666     }
667     else
668     {
669         // the original stream data should be provided
670         if ( !m_pStreamData->m_xOrigSeekable.is() )
671             throw uno::RuntimeException();
672 
673         return m_pStreamData->m_xOrigSeekable->getLength();
674     }
675 }
676 
677 // com::sun::star::beans::XPropertySetInfo
678 // ------------------------------------------------------------------------
getProperties()679 uno::Sequence< beans::Property > SAL_CALL OTruncatedTransactedFileStream::getProperties()
680 {
681     ::osl::MutexGuard aGuard( m_aMutex );
682 
683     uno::Sequence< beans::Property > aProps( 1 );
684     aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
685     aProps[0].Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) );
686     aProps[0].Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY;
687 
688     return aProps;
689 }
690 
691 
692 // ------------------------------------------------------------------------
getPropertyByName(const::rtl::OUString & aName)693 beans::Property SAL_CALL OTruncatedTransactedFileStream::getPropertyByName( const ::rtl::OUString& aName )
694 {
695     ::osl::MutexGuard aGuard( m_aMutex );
696 
697     ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
698 
699     if ( !aName.equals( aTransactionPropName ) )
700         throw beans::UnknownPropertyException();
701 
702     beans::Property aProp;
703     aProp.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
704     aProp.Type = getCppuType( static_cast< uno::Reference< beans::XPropertySet >* >( NULL ) );
705     aProp.Attributes = beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY;
706 
707     return aProp;
708 }
709 
710 
711 // ------------------------------------------------------------------------
hasPropertyByName(const::rtl::OUString & Name)712 ::sal_Bool SAL_CALL OTruncatedTransactedFileStream::hasPropertyByName( const ::rtl::OUString& Name )
713 {
714     ::osl::MutexGuard aGuard( m_aMutex );
715 
716     ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
717     return ( Name.equals( aTransactionPropName ) );
718 }
719 
720 
721 
722 // com::sun::star::beans::XPropertySet
723 // ------------------------------------------------------------------------
getPropertySetInfo()724 uno::Reference< beans::XPropertySetInfo > SAL_CALL OTruncatedTransactedFileStream::getPropertySetInfo()
725 {
726     ::osl::MutexGuard aGuard( m_aMutex );
727 
728     return static_cast< beans::XPropertySetInfo* >( this );
729 }
730 
731 
732 // ------------------------------------------------------------------------
setPropertyValue(const::rtl::OUString & aPropertyName,const uno::Any &)733 void SAL_CALL OTruncatedTransactedFileStream::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& )
734 {
735     ::osl::MutexGuard aGuard( m_aMutex );
736 
737     ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
738     if ( aPropertyName.equals( aTransactionPropName ) )
739         throw beans::PropertyVetoException();
740 
741     throw beans::UnknownPropertyException();
742 }
743 
744 
745 // ------------------------------------------------------------------------
getPropertyValue(const::rtl::OUString & PropertyName)746 uno::Any SAL_CALL OTruncatedTransactedFileStream::getPropertyValue( const ::rtl::OUString& PropertyName )
747 {
748     ::osl::MutexGuard aGuard( m_aMutex );
749 
750     if ( !m_pStreamData )
751         throw io::NotConnectedException();
752 
753     ::rtl::OUString aTransactionPropName( RTL_CONSTASCII_USTRINGPARAM( "TransactionSupport" ) );
754     if ( PropertyName.equals( aTransactionPropName ) )
755     {
756         uno::Reference< embed::XTransactedObject > xObj;
757         if ( m_pStreamData->m_bTransacted )
758             xObj = static_cast< embed::XTransactedObject* >( new OTransactionHelper( this ) );
759 
760         return uno::makeAny( xObj );
761     }
762 
763     throw beans::UnknownPropertyException();
764 }
765 
766 
767 // ------------------------------------------------------------------------
addPropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)768 void SAL_CALL OTruncatedTransactedFileStream::addPropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& )
769 {
770     // not implemented
771 }
772 
773 
774 // ------------------------------------------------------------------------
removePropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)775 void SAL_CALL OTruncatedTransactedFileStream::removePropertyChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener >& )
776 {
777     // not implemented
778 }
779 
780 
781 // ------------------------------------------------------------------------
addVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)782 void SAL_CALL OTruncatedTransactedFileStream::addVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& )
783 {
784     // not implemented
785 }
786 
787 
788 // ------------------------------------------------------------------------
removeVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)789 void SAL_CALL OTruncatedTransactedFileStream::removeVetoableChangeListener( const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener >& )
790 {
791     // not implemented
792 }
793 
794 
795 } // namespace comphelper
796