xref: /trunk/main/io/source/acceptor/acc_pipe.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_io.hxx"
30 #include "osl/security.hxx"
31 #include "acceptor.hxx"
32 #include <com/sun/star/connection/ConnectionSetupException.hpp>
33 
34 #include <cppuhelper/implbase1.hxx>
35 
36 using namespace ::rtl;
37 using namespace ::osl;
38 using namespace ::cppu;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::lang;
41 using namespace ::com::sun::star::connection;
42 using namespace ::com::sun::star::io;
43 
44 
45 namespace io_acceptor
46 {
47 
48 	typedef WeakImplHelper1< XConnection > MyPipeConnection;
49 
50 	class PipeConnection :
51 		public MyPipeConnection
52 	{
53 	public:
54 		PipeConnection( const OUString &sConnectionDescription);
55 		~PipeConnection();
56 
57 		virtual sal_Int32 SAL_CALL read( Sequence< sal_Int8 >& aReadBytes, sal_Int32 nBytesToRead )
58 			throw(::com::sun::star::io::IOException,
59 				  ::com::sun::star::uno::RuntimeException);
60 		virtual void SAL_CALL write( const Sequence< sal_Int8 >& aData )
61 			throw(::com::sun::star::io::IOException,
62 				  ::com::sun::star::uno::RuntimeException);
63 		virtual void SAL_CALL flush(  ) throw(
64 			::com::sun::star::io::IOException,
65 			::com::sun::star::uno::RuntimeException);
66 		virtual void SAL_CALL close(  )
67 			throw(::com::sun::star::io::IOException,
68 				  ::com::sun::star::uno::RuntimeException);
69 		virtual ::rtl::OUString SAL_CALL getDescription(  )
70 			throw(::com::sun::star::uno::RuntimeException);
71 	public:
72 		::osl::StreamPipe m_pipe;
73 		oslInterlockedCount m_nStatus;
74 		OUString m_sDescription;
75 	};
76 
77 
78 
79 	PipeConnection::PipeConnection( const OUString &sConnectionDescription) :
80 		m_nStatus( 0 ),
81 		m_sDescription( sConnectionDescription )
82 	{
83 		g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
84 
85 		// make it unique
86 		m_sDescription += OUString::createFromAscii( ",uniqueValue=" );
87 		m_sDescription += OUString::valueOf(
88             sal::static_int_cast<sal_Int64 >(
89                 reinterpret_cast< sal_IntPtr >(&m_pipe)),
90             10 );
91 	}
92 
93 	PipeConnection::~PipeConnection()
94 	{
95 		g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
96 	}
97 
98 	sal_Int32 PipeConnection::read( Sequence < sal_Int8 > & aReadBytes , sal_Int32 nBytesToRead )
99 		throw(::com::sun::star::io::IOException,
100 			  ::com::sun::star::uno::RuntimeException)
101 	{
102 		if( ! m_nStatus )
103 		{
104 			if( aReadBytes.getLength() < nBytesToRead )
105 			{
106 				aReadBytes.realloc( nBytesToRead );
107 			}
108             sal_Int32 n = m_pipe.read( aReadBytes.getArray(), nBytesToRead );
109             OSL_ASSERT( n >= 0 && n <= aReadBytes.getLength() );
110             if( n < aReadBytes.getLength() )
111             {
112                 aReadBytes.realloc( n );
113             }
114 			return n;
115 		}
116 		else {
117 			throw IOException();
118 		}
119 	}
120 
121 	void PipeConnection::write( const Sequence < sal_Int8 > &seq )
122 			throw(::com::sun::star::io::IOException,
123 				  ::com::sun::star::uno::RuntimeException)
124 	{
125 		if( ! m_nStatus )
126 		{
127 			if( m_pipe.write( seq.getConstArray() , seq.getLength() ) != seq.getLength() )
128 			{
129 				throw IOException();
130 			}
131 		}
132 		else {
133 			throw IOException();
134 		}
135 	}
136 
137 	void PipeConnection::flush( )
138 		throw(	::com::sun::star::io::IOException,
139 				::com::sun::star::uno::RuntimeException)
140 	{
141 	}
142 
143 	void PipeConnection::close()
144 		throw( ::com::sun::star::io::IOException,
145 			   ::com::sun::star::uno::RuntimeException)
146 	{
147 		if(  1 == osl_incrementInterlockedCount( (&m_nStatus) ) )
148 		{
149 			m_pipe.close();
150 		}
151 	}
152 
153 	OUString PipeConnection::getDescription()
154 			throw(::com::sun::star::uno::RuntimeException)
155 	{
156 		return m_sDescription;
157 	}
158 
159 	/***************
160 	 * PipeAcceptor
161 	 **************/
162 	PipeAcceptor::PipeAcceptor( const OUString &sPipeName , const OUString & sConnectionDescription) :
163 		m_sPipeName( sPipeName ),
164 		m_sConnectionDescription( sConnectionDescription ),
165 		m_bClosed( sal_False )
166 	{
167 	}
168 
169 
170 	void PipeAcceptor::init()
171 	{
172 		m_pipe = Pipe( m_sPipeName.pData , osl_Pipe_CREATE , osl::Security() );
173         if( ! m_pipe.is() )
174         {
175 			OUString error = OUString::createFromAscii( "io.acceptor: Couldn't setup pipe " );
176 			error += m_sPipeName;
177             throw ConnectionSetupException( error, Reference< XInterface > () );
178         }
179 	}
180 
181 	Reference< XConnection > PipeAcceptor::accept( )
182 	{
183         Pipe pipe;
184         {
185             MutexGuard guard( m_mutex );
186             pipe = m_pipe;
187         }
188         if( ! pipe.is() )
189         {
190 			OUString error = OUString::createFromAscii( "io.acceptor: pipe already closed" );
191 			error += m_sPipeName;
192             throw ConnectionSetupException( error, Reference< XInterface > () );
193         }
194 		PipeConnection *pConn = new PipeConnection( m_sConnectionDescription );
195 
196 		oslPipeError status = pipe.accept( pConn->m_pipe );
197 
198 		if( m_bClosed )
199 		{
200 			// stopAccepting was called !
201 			delete pConn;
202 			return Reference < XConnection >();
203 		}
204 		else if( osl_Pipe_E_None == status )
205 		{
206 			return Reference < XConnection > ( (XConnection * ) pConn );
207 		}
208 		else
209 		{
210 			OUString error = OUString::createFromAscii( "io.acceptor: Couldn't setup pipe " );
211 			error += m_sPipeName;
212 			throw ConnectionSetupException( error, Reference< XInterface > ());
213 		}
214 	}
215 
216 	void PipeAcceptor::stopAccepting()
217 	{
218 		m_bClosed = sal_True;
219         Pipe pipe;
220         {
221             MutexGuard guard( m_mutex );
222             pipe = m_pipe;
223             m_pipe.clear();
224         }
225         if( pipe.is() )
226         {
227             pipe.close();
228         }
229 	}
230 }
231