Update ooo320-m1
[ooovba.git] / bridges / source / remote / static / proxy.cxx
bloba72d40ca858648f1bb122deaf83466dceae97f26
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: proxy.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_bridges.hxx"
33 #if OSL_DEBUG_LEVEL == 0
34 # ifndef NDEBUG
35 # define NDEBUG
36 # endif
37 #endif
38 #include <assert.h>
39 #include <sal/alloca.h>
40 #include <bridges/remote/proxy.hxx>
41 #include <bridges/remote/context.h>
43 #include <uno/data.h>
44 #include <uno/mapping.hxx>
45 #include <uno/environment.h>
47 #include <com/sun/star/uno/Any.hxx>
49 #include <bridges/remote/bridgeimpl.hxx>
51 #include "remote_types.hxx"
53 #if OSL_DEBUG_LEVEL > 1
54 #include <bridges/remote/counter.hxx>
55 static MyCounter thisCounter( "DEBUG : Remote2UnoProxy");
56 #endif
58 using namespace ::bridges_remote;
59 using namespace ::com::sun::star::uno;
61 extern "C" {
63 void SAL_CALL remote_release( void *pRemoteI )
65 ((remote_Interface * )pRemoteI)->release( (remote_Interface * ) pRemoteI );
70 namespace bridges_remote {
72 void freeRemote2UnoProxy(uno_ExtEnvironment *, void * proxy) {
73 delete static_cast< Remote2UnoProxy * >(proxy);
76 void acquireRemote2UnoProxy( uno_Interface *pThis )
78 Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
79 if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
81 p->m_pEnvUno->pExtEnv->registerProxyInterface(
82 p->m_pEnvUno->pExtEnv,
83 (void**)&pThis,
84 freeRemote2UnoProxy,
85 p->m_sOid.pData,
86 p->m_pType );
87 assert( (uno_Interface *)p == pThis );
91 void releaseRemote2UnoProxy( uno_Interface *pThis )
93 Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
94 if ( 0 == osl_decrementInterlockedCount( &(p->m_nRef) ))
96 p->m_pEnvUno->pExtEnv->revokeInterface( p->m_pEnvUno->pExtEnv, p );
100 void SAL_CALL dispatchRemote2UnoProxy(
101 uno_Interface * pUnoI,
102 typelib_TypeDescription const * pType,
103 void * pReturn,
104 void * ppArgs[],
105 uno_Any ** ppException )
107 Remote2UnoProxy *p = ( Remote2UnoProxy * ) pUnoI;
108 RemoteThreadCounter counter( p->m_pEnvRemote );
110 typelib_InterfaceMethodTypeDescription *pMethodType = 0;
111 typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
112 typelib_TypeDescription *pReturnType = 0;
113 typelib_TypeDescription **ppArgType = 0;
114 sal_Int32 nArgCount = 0;
115 sal_Bool *pbIsIn = 0;
116 sal_Bool *pbIsOut = 0;
117 sal_Bool *pbConversionNeeded = 0;
118 sal_Bool bConversionNeededForReturn = 0;
120 //--------------------------------
121 // Collect all needed types !
122 //--------------------------------
123 if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass )
125 pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType;
126 if( pReturn )
128 TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef );
129 bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
131 else
133 nArgCount = 1;
134 ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) );
135 pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
136 pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
137 pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) );
139 pbIsIn[0] = sal_True;
140 pbIsOut[0] = sal_False;
141 ppArgType[0] = 0;
142 TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef );
143 pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] );
147 if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass )
149 pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType;
150 TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef );
151 bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
152 nArgCount = pMethodType->nParams;
153 ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount );
154 pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
155 pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
156 pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) * nArgCount );
157 sal_Int32 i;
158 for( i = 0 ; i < nArgCount ; i ++ )
160 ppArgType[i] = 0;
161 TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef );
162 pbIsIn[i] = pMethodType->pParams[i].bIn;
163 pbIsOut[i] = pMethodType->pParams[i].bOut;
164 pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] );
168 void *pRemoteReturn = 0;
169 if( pReturnType )
171 if( bConversionNeededForReturn )
173 pRemoteReturn = alloca( pReturnType->nSize );
175 else
177 pRemoteReturn = pReturn;
181 void ** ppRemoteArgs = 0;
182 if( nArgCount )
184 ppRemoteArgs = (void**) alloca( sizeof( void * ) * nArgCount );
187 sal_Int32 i;
188 for( i = 0 ; i < nArgCount ; i ++ )
190 if( pbConversionNeeded[i] )
192 ppRemoteArgs[i] = alloca( ppArgType[i]->nSize );
194 if( pbIsIn[i] ) {
195 uno_copyAndConvertData(
196 ppRemoteArgs[i],
197 ppArgs[i],
198 ppArgType[i],
199 p->m_mapUno2Remote.get() );
202 else
204 ppRemoteArgs[i] = ppArgs[i];
208 uno_Any any;
209 uno_Any *pAny = &any;
211 p->m_pRemoteI->pDispatcher( p->m_pRemoteI,
212 pType,
213 pRemoteReturn,
214 ppRemoteArgs,
215 &pAny );
217 if( ! pAny )
219 if( pReturn && bConversionNeededForReturn )
221 uno_copyAndConvertData(
222 pReturn ,
223 pRemoteReturn,
224 pReturnType,
225 p->m_mapRemote2Uno.get() );
226 uno_destructData( pRemoteReturn , pReturnType , remote_release );
229 sal_Int32 j;
230 for( j = 0 ; j < nArgCount ; j ++ )
232 if( pbConversionNeeded[j] )
234 if( pbIsIn[j] ) {
235 if( pbIsOut[j] ) {
236 uno_destructData( ppArgs[j] ,
237 ppArgType[j] ,
238 0 );
239 uno_copyAndConvertData( ppArgs[j] ,
240 ppRemoteArgs[j],
241 ppArgType[j],
242 p->m_mapRemote2Uno.get() );
245 else // pure out
247 uno_copyAndConvertData( ppArgs[j] ,
248 ppRemoteArgs[j],
249 ppArgType[j],
250 p->m_mapRemote2Uno.get() );
252 uno_destructData( ppRemoteArgs[j],
253 ppArgType[j],
254 remote_release );
257 *ppException = 0;
259 else
261 // -----------------------
262 // an exception occured
263 // -----------------------
264 typelib_TypeDescription *pAnyType = 0;
265 getCppuType( (::com::sun::star::uno::Any*) 0 ).getDescription( &pAnyType );
266 uno_copyAndConvertData( *ppException ,
267 pAny ,
268 pAnyType,
269 p->m_mapRemote2Uno.get() );
270 uno_destructData( pAny , pAnyType , remote_release );
271 typelib_typedescription_release( pAnyType );
273 // destruct remote in parameters ( out parameters have not been constructed )
274 for( i = 0 ; i < nArgCount ; i ++ )
276 if( pbConversionNeeded[i] && pbIsIn[i] )
278 uno_destructData( ppRemoteArgs[i],
279 ppArgType[i],
280 remote_release );
285 //--------------------------
286 // release all acquired types
287 //--------------------------
288 if( pReturnType )
290 TYPELIB_DANGER_RELEASE( pReturnType );
292 for( i = 0 ; i < nArgCount ; i ++ )
294 TYPELIB_DANGER_RELEASE( ppArgType[ i] );
299 Remote2UnoProxy::Remote2UnoProxy( remote_Interface *pRemoteI,
300 rtl_uString *pOid,
301 typelib_InterfaceTypeDescription *pType,
302 uno_Environment *pEnvUno,
303 uno_Environment *pEnvRemote ) :
304 m_sOid( pOid ),
305 m_pType( pType ),
306 m_pRemoteI( pRemoteI ),
307 m_pEnvUno( pEnvUno ),
308 m_pEnvRemote( pEnvRemote ),
309 m_mapRemote2Uno( pEnvRemote, pEnvUno ),
310 m_mapUno2Remote( pEnvUno , pEnvRemote ),
311 m_nRef( 1 )
313 typelib_typedescription_acquire( (typelib_TypeDescription * ) m_pType );
314 m_pEnvUno->acquire( m_pEnvUno );
315 m_pEnvRemote->acquire( m_pEnvRemote );
317 acquire = acquireRemote2UnoProxy;
318 release = releaseRemote2UnoProxy;
319 pDispatcher = dispatchRemote2UnoProxy;
321 m_pEnvRemote->pExtEnv->registerInterface(
322 m_pEnvRemote->pExtEnv,
323 (void**)&m_pRemoteI,
324 m_sOid.pData,
325 m_pType );
326 m_pRemoteI->acquire( m_pRemoteI );
328 #if OSL_DEBUG_LEVEL > 1
329 thisCounter.acquire();
330 #endif
333 Remote2UnoProxy::~Remote2UnoProxy()
335 // revoke external ref (oid)
336 m_pEnvRemote->pExtEnv->revokeInterface( m_pEnvRemote->pExtEnv , m_pRemoteI );
338 typelib_typedescription_release( (typelib_TypeDescription * )m_pType );
339 m_pRemoteI->release( m_pRemoteI );
340 m_pEnvUno->release( m_pEnvUno );
341 m_pEnvRemote->release( m_pEnvRemote );
342 #if OSL_DEBUG_LEVEL > 1
343 thisCounter.release();
344 #endif
347 } // end namespace bridge_remote