Update ooo320-m1
[ooovba.git] / io / source / stm / opump.cxx
blob331183db88e5a7998881ab28ed9f511508a37382
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: opump.cxx,v $
10 * $Revision: 1.13 $
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_io.hxx"
34 #include <stdio.h>
36 #include <osl/diagnose.h>
38 #include <com/sun/star/io/XActiveDataSource.hpp>
39 #include <com/sun/star/io/XActiveDataSink.hpp>
40 #include <com/sun/star/io/XActiveDataControl.hpp>
41 #include <com/sun/star/io/XConnectable.hpp>
42 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
43 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
44 #include <com/sun/star/lang/XServiceInfo.hpp>
45 #include <com/sun/star/registry/XRegistryKey.hpp>
47 #include <uno/dispatcher.h>
48 #include <uno/mapping.hxx>
49 #include <cppuhelper/implbase5.hxx>
50 #include <cppuhelper/factory.hxx>
51 #include <cppuhelper/interfacecontainer.hxx>
52 #include <osl/mutex.hxx>
53 #include <osl/thread.h>
56 using namespace osl;
57 using namespace std;
58 using namespace rtl;
59 using namespace cppu;
60 using namespace com::sun::star::uno;
61 using namespace com::sun::star::lang;
62 using namespace com::sun::star::registry;
63 using namespace com::sun::star::io;
65 #include "factreg.hxx"
67 namespace io_stm {
69 class Pump : public WeakImplHelper5<
70 XActiveDataSource, XActiveDataSink, XActiveDataControl, XConnectable, XServiceInfo >
72 Mutex m_aMutex;
73 oslThread m_aThread;
75 Reference< XConnectable > m_xPred;
76 Reference< XConnectable > m_xSucc;
77 Reference< XInputStream > m_xInput;
78 Reference< XOutputStream > m_xOutput;
79 OInterfaceContainerHelper m_cnt;
80 sal_Bool m_closeFired;
82 void run();
83 static void static_run( void* pObject );
85 void close();
86 void fireClose();
87 void fireStarted();
88 void fireTerminated();
89 void fireError( const Any &a );
91 public:
92 Pump();
93 virtual ~Pump();
95 // XActiveDataSource
96 virtual void SAL_CALL setOutputStream( const Reference< ::com::sun::star::io::XOutputStream >& xOutput ) throw();
97 virtual Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream() throw();
99 // XActiveDataSink
100 virtual void SAL_CALL setInputStream( const Reference< ::com::sun::star::io::XInputStream >& xStream ) throw();
101 virtual Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream() throw();
103 // XActiveDataControl
104 virtual void SAL_CALL addListener( const Reference< ::com::sun::star::io::XStreamListener >& xListener ) throw();
105 virtual void SAL_CALL removeListener( const Reference< ::com::sun::star::io::XStreamListener >& xListener ) throw();
106 virtual void SAL_CALL start() throw( RuntimeException );
107 virtual void SAL_CALL terminate() throw();
109 // XConnectable
110 virtual void SAL_CALL setPredecessor( const Reference< ::com::sun::star::io::XConnectable >& xPred ) throw();
111 virtual Reference< ::com::sun::star::io::XConnectable > SAL_CALL getPredecessor() throw();
112 virtual void SAL_CALL setSuccessor( const Reference< ::com::sun::star::io::XConnectable >& xSucc ) throw();
113 virtual Reference< ::com::sun::star::io::XConnectable > SAL_CALL getSuccessor() throw();
115 public: // XServiceInfo
116 virtual OUString SAL_CALL getImplementationName() throw( );
117 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw( );
118 virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw( );
121 Pump::Pump() : m_aThread( 0 ),
122 m_cnt( m_aMutex ),
123 m_closeFired( sal_False )
125 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
128 Pump::~Pump()
130 // exit gracefully
131 if( m_aThread )
133 osl_joinWithThread( m_aThread );
134 osl_destroyThread( m_aThread );
136 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
139 void Pump::fireError( const Any & exception )
141 OInterfaceIteratorHelper iter( m_cnt );
142 while( iter.hasMoreElements() )
146 static_cast< XStreamListener * > ( iter.next() )->error( exception );
148 catch ( RuntimeException &e )
150 OString sMessage = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
151 OSL_ENSURE( !"com.sun.star.comp.stoc.Pump: unexpected exception during calling listeners", sMessage.getStr() );
156 void Pump::fireClose()
158 sal_Bool bFire = sal_False;
160 MutexGuard guard( m_aMutex );
161 if( ! m_closeFired )
163 m_closeFired = sal_True;
164 bFire = sal_True;
168 if( bFire )
170 OInterfaceIteratorHelper iter( m_cnt );
171 while( iter.hasMoreElements() )
175 static_cast< XStreamListener * > ( iter.next() )->closed( );
177 catch ( RuntimeException &e )
179 OString sMessage = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
180 OSL_ENSURE( !"com.sun.star.comp.stoc.Pump: unexpected exception during calling listeners", sMessage.getStr() );
186 void Pump::fireStarted()
188 OInterfaceIteratorHelper iter( m_cnt );
189 while( iter.hasMoreElements() )
193 static_cast< XStreamListener * > ( iter.next() )->started( );
195 catch ( RuntimeException &e )
197 OString sMessage = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
198 OSL_ENSURE( !"com.sun.star.comp.stoc.Pump: unexpected exception during calling listeners", sMessage.getStr() );
203 void Pump::fireTerminated()
205 OInterfaceIteratorHelper iter( m_cnt );
206 while( iter.hasMoreElements() )
210 static_cast< XStreamListener * > ( iter.next() )->terminated();
212 catch ( RuntimeException &e )
214 OString sMessage = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
215 OSL_ENSURE( !"com.sun.star.comp.stoc.Pump: unexpected exception during calling listeners", sMessage.getStr() );
222 void Pump::close()
224 // close streams and release references
225 Reference< XInputStream > rInput;
226 Reference< XOutputStream > rOutput;
228 MutexGuard guard( m_aMutex );
229 rInput = m_xInput;
230 m_xInput.clear();
232 rOutput = m_xOutput;
233 m_xOutput.clear();
234 m_xSucc.clear();
235 m_xPred.clear();
237 if( rInput.is() )
241 rInput->closeInput();
243 catch( Exception & )
245 // go down calm
248 if( rOutput.is() )
252 rOutput->closeOutput();
254 catch( Exception & )
256 // go down calm
261 void Pump::static_run( void* pObject )
263 ((Pump*)pObject)->run();
264 ((Pump*)pObject)->release();
267 void Pump::run()
271 fireStarted();
274 Reference< XInputStream > rInput;
275 Reference< XOutputStream > rOutput;
277 Guard< Mutex > aGuard( m_aMutex );
278 rInput = m_xInput;
279 rOutput = m_xOutput;
282 if( ! rInput.is() )
284 NotConnectedException exception(
285 OUString::createFromAscii( "no input stream set" ) , Reference<XInterface>((OWeakObject*)this) );
286 throw exception;
288 Sequence< sal_Int8 > aData;
289 while( rInput->readSomeBytes( aData, 65536 ) )
291 if( ! rOutput.is() )
293 NotConnectedException exception(
294 OUString::createFromAscii( "no output stream set" ) , Reference<XInterface>( (OWeakObject*)this) );
295 throw exception;
297 rOutput->writeBytes( aData );
298 osl_yieldThread();
301 catch ( IOException & e )
303 fireError( makeAny( e ) );
305 catch ( RuntimeException & e )
307 fireError( makeAny( e ) );
309 catch ( Exception & e )
311 fireError( makeAny( e ) );
314 close();
315 fireClose();
317 catch ( com::sun::star::uno::Exception &e )
319 // we are the last on the stack.
320 // this is to avoid crashing the program, when e.g. a bridge crashes
321 OString sMessage = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
322 OSL_ENSURE( !"com.sun.star.comp.stoc.Pump: unexpected exception", sMessage.getStr() );
326 // ------------------------------------------------------------
329 * XConnectable
332 void Pump::setPredecessor( const Reference< XConnectable >& xPred ) throw()
334 Guard< Mutex > aGuard( m_aMutex );
335 m_xPred = xPred;
338 // ------------------------------------------------------------
340 Reference< XConnectable > Pump::getPredecessor() throw()
342 Guard< Mutex > aGuard( m_aMutex );
343 return m_xPred;
346 // ------------------------------------------------------------
348 void Pump::setSuccessor( const Reference< XConnectable >& xSucc ) throw()
350 Guard< Mutex > aGuard( m_aMutex );
351 m_xSucc = xSucc;
354 // ------------------------------------------------------------
356 Reference< XConnectable > Pump::getSuccessor() throw()
358 Guard< Mutex > aGuard( m_aMutex );
359 return m_xSucc;
362 // -----------------------------------------------------------------
365 * XActiveDataControl
368 void Pump::addListener( const Reference< XStreamListener >& xListener ) throw()
370 m_cnt.addInterface( xListener );
373 // ------------------------------------------------------------
375 void Pump::removeListener( const Reference< XStreamListener >& xListener ) throw()
377 m_cnt.removeInterface( xListener );
380 // ------------------------------------------------------------
382 void Pump::start() throw( RuntimeException )
384 Guard< Mutex > aGuard( m_aMutex );
385 m_aThread = osl_createSuspendedThread((oslWorkerFunction)Pump::static_run,this);
386 if( m_aThread )
388 // will be released by OPump::static_run
389 acquire();
390 osl_resumeThread( m_aThread );
392 else
394 throw RuntimeException(
395 OUString( RTL_CONSTASCII_USTRINGPARAM( "Pump::start Couldn't create worker thread" )),
396 *this);
400 // ------------------------------------------------------------
402 void Pump::terminate() throw()
404 close();
406 // wait for the worker to die
407 if( m_aThread )
408 osl_joinWithThread( m_aThread );
410 fireTerminated();
411 fireClose();
414 // ------------------------------------------------------------
417 * XActiveDataSink
420 void Pump::setInputStream( const Reference< XInputStream >& xStream ) throw()
422 Guard< Mutex > aGuard( m_aMutex );
423 m_xInput = xStream;
424 Reference< XConnectable > xConnect( xStream, UNO_QUERY );
425 if( xConnect.is() )
426 xConnect->setSuccessor( this );
427 // data transfer starts in XActiveDataControl::start
430 // ------------------------------------------------------------
432 Reference< XInputStream > Pump::getInputStream() throw()
434 Guard< Mutex > aGuard( m_aMutex );
435 return m_xInput;
438 // ------------------------------------------------------------
441 * XActiveDataSource
444 void Pump::setOutputStream( const Reference< XOutputStream >& xOut ) throw()
446 Guard< Mutex > aGuard( m_aMutex );
447 m_xOutput = xOut;
448 Reference< XConnectable > xConnect( xOut, UNO_QUERY );
449 if( xConnect.is() )
450 xConnect->setPredecessor( this );
451 // data transfer starts in XActiveDataControl::start
454 // ------------------------------------------------------------
456 Reference< XOutputStream > Pump::getOutputStream() throw()
458 Guard< Mutex > aGuard( m_aMutex );
459 return m_xOutput;
463 // XServiceInfo
464 OUString Pump::getImplementationName() throw( )
466 return OPumpImpl_getImplementationName();
469 // XServiceInfo
470 sal_Bool Pump::supportsService(const OUString& ServiceName) throw( )
472 Sequence< OUString > aSNL = getSupportedServiceNames();
473 const OUString * pArray = aSNL.getConstArray();
475 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
476 if( pArray[i] == ServiceName )
477 return sal_True;
479 return sal_False;
482 // XServiceInfo
483 Sequence< OUString > Pump::getSupportedServiceNames(void) throw( )
485 return OPumpImpl_getSupportedServiceNames();
489 Reference< XInterface > SAL_CALL OPumpImpl_CreateInstance( const Reference< XComponentContext > & ) throw (Exception)
491 return Reference< XInterface >( *new Pump );
494 OUString OPumpImpl_getImplementationName()
496 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.io.Pump") );
499 Sequence<OUString> OPumpImpl_getSupportedServiceNames(void)
501 OUString s( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.Pump" ) );
502 Sequence< OUString > seq( &s , 1 );
503 return seq;