update dev300-m58
[ooovba.git] / sfx2 / source / doc / opostponedtruncationstream.cxx
blobb69b54325ba5e059703b78abcd19e0e44899a526
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: opostponedtruncationstream.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
33 #include <osl/diagnose.h>
35 #include <opostponedtruncationstream.hxx>
37 using namespace ::com::sun::star;
39 // ========================================================================
40 struct PTFStreamData_Impl
42 uno::Reference< ucb::XSimpleFileAccess > m_xFileAccess;
43 sal_Bool m_bDelete;
44 ::rtl::OUString m_aURL;
46 // the streams below are not visible from outside so there is no need to remember position
48 // original stream related members
49 uno::Reference< io::XStream > m_xOrigStream;
50 uno::Reference< io::XTruncate > m_xOrigTruncate;
51 uno::Reference< io::XSeekable > m_xOrigSeekable;
52 uno::Reference< io::XInputStream > m_xOrigInStream;
53 uno::Reference< io::XOutputStream > m_xOrigOutStream;
55 sal_Bool m_bInOpen;
56 sal_Bool m_bOutOpen;
58 sal_Bool m_bPostponedTruncate;
61 PTFStreamData_Impl(
62 const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess,
63 sal_Bool bDelete,
64 const ::rtl::OUString& aURL,
65 const uno::Reference< io::XStream >& xOrigStream,
66 const uno::Reference< io::XTruncate >& xOrigTruncate,
67 const uno::Reference< io::XSeekable >& xOrigSeekable,
68 const uno::Reference< io::XInputStream >& xOrigInStream,
69 const uno::Reference< io::XOutputStream >& xOrigOutStream )
70 : m_xFileAccess( xFileAccess )
71 , m_bDelete( bDelete )
72 , m_aURL( aURL )
73 , m_xOrigStream( xOrigStream )
74 , m_xOrigTruncate( xOrigTruncate )
75 , m_xOrigSeekable( xOrigSeekable )
76 , m_xOrigInStream( xOrigInStream )
77 , m_xOrigOutStream( xOrigOutStream )
78 , m_bInOpen( sal_False )
79 , m_bOutOpen( sal_False )
80 , m_bPostponedTruncate( sal_True )
83 void NoPostponing()
85 m_bDelete = sal_False;
86 m_bPostponedTruncate = sal_False;
90 // ========================================================================
91 // ------------------------------------------------------------------------
92 OPostponedTruncationFileStream::OPostponedTruncationFileStream(
93 const ::rtl::OUString& aURL,
94 const uno::Reference< lang::XMultiServiceFactory >& /*xFactory*/,
95 const uno::Reference< ucb::XSimpleFileAccess >& xFileAccess,
96 const uno::Reference< io::XStream >& xOrigStream,
97 sal_Bool bDelete )
98 : m_pStreamData( NULL )
100 if ( !xFileAccess.is() || !xOrigStream.is() )
101 throw uno::RuntimeException();
103 uno::Reference< io::XTruncate > xOrigTruncate( xOrigStream, uno::UNO_QUERY_THROW );
104 uno::Reference< io::XSeekable > xOrigSeekable( xOrigStream, uno::UNO_QUERY_THROW );
105 uno::Reference< io::XInputStream > xOrigInStream = xOrigStream->getInputStream();
106 uno::Reference< io::XOutputStream > xOrigOutStream = xOrigStream->getOutputStream();
107 if ( !xOrigInStream.is() || !xOrigOutStream.is() )
108 throw uno::RuntimeException();
110 m_pStreamData = new PTFStreamData_Impl( xFileAccess, bDelete, aURL,
111 xOrigStream, xOrigTruncate, xOrigSeekable, xOrigInStream, xOrigOutStream );
114 // ------------------------------------------------------------------------
115 OPostponedTruncationFileStream::~OPostponedTruncationFileStream()
117 CloseAll_Impl();
120 // ------------------------------------------------------------------------
121 void OPostponedTruncationFileStream::CloseAll_Impl()
123 if ( m_pStreamData )
125 sal_Bool bDelete = m_pStreamData->m_bDelete;
126 ::rtl::OUString aURL = m_pStreamData->m_aURL;
127 uno::Reference< ucb::XSimpleFileAccess > xFileAccess = m_pStreamData->m_xFileAccess;
129 delete m_pStreamData;
130 m_pStreamData = NULL;
132 if ( bDelete && xFileAccess.is() && aURL.getLength() )
134 // delete the file
137 xFileAccess->kill( aURL );
138 } catch( uno::Exception& )
140 OSL_ENSURE( sal_False, "Could not remove the file!" );
146 // ------------------------------------------------------------------------
147 void OPostponedTruncationFileStream::CheckScheduledTruncation_Impl()
149 if ( !m_pStreamData )
150 throw io::NotConnectedException();
152 if ( m_pStreamData->m_bPostponedTruncate )
154 // the original stream data should be provided
155 if ( !m_pStreamData->m_xOrigTruncate.is() )
156 throw uno::RuntimeException();
158 m_pStreamData->m_xOrigTruncate->truncate();
159 m_pStreamData->NoPostponing();
163 // com::sun::star::io::XStream
164 // ------------------------------------------------------------------------
165 uno::Reference< io::XInputStream > SAL_CALL OPostponedTruncationFileStream::getInputStream( )
166 throw (uno::RuntimeException)
168 ::osl::MutexGuard aGuard( m_aMutex );
170 if ( m_pStreamData )
171 m_pStreamData->m_bInOpen = sal_True;
172 return static_cast< io::XInputStream* >( this );
176 // ------------------------------------------------------------------------
177 uno::Reference< io::XOutputStream > SAL_CALL OPostponedTruncationFileStream::getOutputStream( )
178 throw (uno::RuntimeException)
180 ::osl::MutexGuard aGuard( m_aMutex );
182 if ( m_pStreamData )
183 m_pStreamData->m_bOutOpen = sal_True;
184 return static_cast< io::XOutputStream* >( this );
189 // com::sun::star::io::XInputStream
190 // ------------------------------------------------------------------------
191 ::sal_Int32 SAL_CALL OPostponedTruncationFileStream::readBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead )
192 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
194 ::osl::MutexGuard aGuard( m_aMutex );
196 if ( !m_pStreamData )
197 throw io::NotConnectedException();
199 if ( m_pStreamData->m_bPostponedTruncate )
201 // the stream must behave as truncated one
202 aData.realloc( 0 );
203 return 0;
205 else
207 // the original stream data should be provided
208 if ( !m_pStreamData->m_xOrigInStream.is() )
209 throw uno::RuntimeException();
211 return m_pStreamData->m_xOrigInStream->readBytes( aData, nBytesToRead );
216 // ------------------------------------------------------------------------
217 ::sal_Int32 SAL_CALL OPostponedTruncationFileStream::readSomeBytes( uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead )
218 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
220 ::osl::MutexGuard aGuard( m_aMutex );
222 if ( !m_pStreamData )
223 throw io::NotConnectedException();
225 if ( m_pStreamData->m_bPostponedTruncate )
227 // the stream must behave as truncated one
228 aData.realloc( 0 );
229 return 0;
231 else
233 // the original stream data should be provided
234 if ( !m_pStreamData->m_xOrigInStream.is() )
235 throw uno::RuntimeException();
237 return m_pStreamData->m_xOrigInStream->readBytes( aData, nMaxBytesToRead );
241 // ------------------------------------------------------------------------
242 void SAL_CALL OPostponedTruncationFileStream::skipBytes( ::sal_Int32 nBytesToSkip )
243 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
245 ::osl::MutexGuard aGuard( m_aMutex );
247 if ( !m_pStreamData )
248 throw io::NotConnectedException();
250 if ( m_pStreamData->m_bPostponedTruncate )
252 // the stream must behave as truncated one
253 if ( nBytesToSkip > 0 )
254 throw io::BufferSizeExceededException();
256 return;
258 else
260 // the original stream data should be provided
261 if ( !m_pStreamData->m_xOrigInStream.is() )
262 throw uno::RuntimeException();
264 m_pStreamData->m_xOrigInStream->skipBytes( nBytesToSkip );
269 // ------------------------------------------------------------------------
270 ::sal_Int32 SAL_CALL OPostponedTruncationFileStream::available( )
271 throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
273 ::osl::MutexGuard aGuard( m_aMutex );
275 if ( !m_pStreamData )
276 throw io::NotConnectedException();
278 if ( m_pStreamData->m_bPostponedTruncate )
280 // the stream must behave as truncated one
281 return 0;
283 else
285 // the original stream data should be provided
286 if ( !m_pStreamData->m_xOrigInStream.is() )
287 throw uno::RuntimeException();
289 return m_pStreamData->m_xOrigInStream->available();
294 // ------------------------------------------------------------------------
295 void SAL_CALL OPostponedTruncationFileStream::closeInput()
296 throw (io::NotConnectedException, io::IOException, uno::RuntimeException)
298 ::osl::MutexGuard aGuard( m_aMutex );
300 if ( !m_pStreamData )
301 throw io::NotConnectedException();
303 m_pStreamData->m_bInOpen = sal_False;
304 if ( !m_pStreamData->m_bOutOpen )
305 CloseAll_Impl();
310 // com::sun::star::io::XOutputStream
311 // ------------------------------------------------------------------------
312 void SAL_CALL OPostponedTruncationFileStream::writeBytes( const uno::Sequence< ::sal_Int8 >& aData )
313 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
315 ::osl::MutexGuard aGuard( m_aMutex );
317 if ( !m_pStreamData )
318 throw io::NotConnectedException();
320 // writing method must check the truncation
321 CheckScheduledTruncation_Impl();
323 // the original stream data should be provided
324 if ( !m_pStreamData->m_xOrigOutStream.is() )
325 throw uno::RuntimeException();
327 m_pStreamData->m_xOrigOutStream->writeBytes( aData );
331 // ------------------------------------------------------------------------
332 void SAL_CALL OPostponedTruncationFileStream::flush( )
333 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
335 ::osl::MutexGuard aGuard( m_aMutex );
337 if ( !m_pStreamData )
339 OSL_ENSURE( sal_False, "flush() call on closed stream!\n" );
340 return;
341 // in future throw exception, for now some code might call flush() on closed stream
342 // since file ucp implementation allows it
343 // throw io::NotConnectedException();
346 if ( m_pStreamData->m_bPostponedTruncate )
348 // it is no writing call, thus must be ignored
349 return;
351 else
353 // the original stream data should be provided
354 if ( !m_pStreamData->m_xOrigOutStream.is() )
355 throw uno::RuntimeException();
357 m_pStreamData->m_xOrigOutStream->flush();
362 // ------------------------------------------------------------------------
363 void SAL_CALL OPostponedTruncationFileStream::closeOutput( )
364 throw (io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
366 ::osl::MutexGuard aGuard( m_aMutex );
368 if ( !m_pStreamData )
369 throw io::NotConnectedException();
371 m_pStreamData->m_bOutOpen = sal_False;
372 if ( !m_pStreamData->m_bInOpen )
373 CloseAll_Impl();
378 // com::sun::star::io::XTruncate
379 // ------------------------------------------------------------------------
380 void SAL_CALL OPostponedTruncationFileStream::truncate( )
381 throw (io::IOException, uno::RuntimeException)
383 ::osl::MutexGuard aGuard( m_aMutex );
385 if ( !m_pStreamData )
386 throw io::NotConnectedException();
388 if ( m_pStreamData->m_bPostponedTruncate )
390 // the truncation is already scheduled, ignore
391 return;
393 else
395 // the original stream data should be provided
396 if ( !m_pStreamData->m_xOrigTruncate.is() )
397 throw uno::RuntimeException();
399 m_pStreamData->m_xOrigTruncate->truncate();
405 // com::sun::star::io::XSeekable
406 // ------------------------------------------------------------------------
407 void SAL_CALL OPostponedTruncationFileStream::seek( ::sal_Int64 location )
408 throw (lang::IllegalArgumentException, io::IOException, uno::RuntimeException)
410 ::osl::MutexGuard aGuard( m_aMutex );
412 if ( !m_pStreamData )
413 throw io::NotConnectedException();
415 if ( m_pStreamData->m_bPostponedTruncate )
417 if ( location > 0 )
418 throw lang::IllegalArgumentException();
420 return;
422 else
424 // the original stream data should be provided
425 if ( !m_pStreamData->m_xOrigSeekable.is() )
426 throw uno::RuntimeException();
428 m_pStreamData->m_xOrigSeekable->seek( location );
433 // ------------------------------------------------------------------------
434 ::sal_Int64 SAL_CALL OPostponedTruncationFileStream::getPosition( )
435 throw (io::IOException, uno::RuntimeException)
437 ::osl::MutexGuard aGuard( m_aMutex );
439 if ( !m_pStreamData )
440 throw io::NotConnectedException();
442 if ( m_pStreamData->m_bPostponedTruncate )
444 return 0;
446 else
448 // the original stream data should be provided
449 if ( !m_pStreamData->m_xOrigSeekable.is() )
450 throw uno::RuntimeException();
452 return m_pStreamData->m_xOrigSeekable->getPosition();
457 // ------------------------------------------------------------------------
458 ::sal_Int64 SAL_CALL OPostponedTruncationFileStream::getLength( )
459 throw (io::IOException, uno::RuntimeException)
461 ::osl::MutexGuard aGuard( m_aMutex );
463 if ( !m_pStreamData )
464 throw io::NotConnectedException();
466 if ( m_pStreamData->m_bPostponedTruncate )
468 return 0;
470 else
472 // the original stream data should be provided
473 if ( !m_pStreamData->m_xOrigSeekable.is() )
474 throw uno::RuntimeException();
476 return m_pStreamData->m_xOrigSeekable->getLength();
480 // ------------------------------------------------------------------------
481 void SAL_CALL OPostponedTruncationFileStream::waitForCompletion()
482 throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
484 if ( !m_pStreamData )
485 throw io::NotConnectedException();
487 if ( m_pStreamData->m_bPostponedTruncate )
488 return;
490 uno::Reference< io::XAsyncOutputMonitor > asyncOutputMonitor( m_pStreamData->m_xOrigOutStream, uno::UNO_QUERY );
491 if ( asyncOutputMonitor.is() )
492 asyncOutputMonitor->waitForCompletion();