Update ooo320-m1
[ooovba.git] / bridges / source / remote / static / stub.cxx
blob3abc230c8db46725677626bc14f301d8ddad7ce6
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: stub.cxx,v $
10 * $Revision: 1.11 $
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 #include <sal/alloca.h>
34 #include <osl/diagnose.h>
36 #include <uno/data.h>
37 #include <uno/mapping.hxx>
39 #include <bridges/remote/stub.hxx>
40 #include <bridges/remote/proxy.hxx>
41 #include <bridges/remote/context.h>
42 #include <bridges/remote/bridgeimpl.hxx>
44 #include "remote_types.hxx"
46 #if OSL_DEBUG_LEVEL > 1
47 #include <bridges/remote/counter.hxx>
48 static MyCounter thisCounter( "DEBUG : Uno2RemoteStub");
49 #endif
51 using namespace ::com::sun::star::uno;
52 using namespace bridges_remote;
54 extern "C" {
56 void SAL_CALL thisRelease( remote_Interface *pThis )
58 Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis;
59 if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
61 p->m_pEnvRemote->pExtEnv->revokeInterface( p->m_pEnvRemote->pExtEnv, pThis );
65 void SAL_CALL thisDispatch(
66 remote_Interface * pRemoteI,
67 typelib_TypeDescription const * pType,
68 void * pReturn,
69 void * ppArgs[],
70 uno_Any ** ppException )
72 Uno2RemoteStub *p = ( Uno2RemoteStub * ) pRemoteI;
74 RemoteThreadCounter counter( p->m_pEnvRemote );
76 typelib_InterfaceMethodTypeDescription *pMethodType = 0;
77 typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
78 typelib_TypeDescription *pReturnType = 0;
79 typelib_TypeDescription **ppArgType = 0;
80 sal_Int32 nArgCount = 0;
81 sal_Bool *pbIsIn = 0;
82 sal_Bool *pbIsOut = 0;
83 sal_Bool bConversionNeededForReturn = sal_False;
84 sal_Bool *pbConversionNeeded = 0;
86 sal_Int32 i;
87 //--------------------------------
88 // Collect all needed types !
89 //--------------------------------
90 if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass )
92 pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType;
93 if( pReturn )
95 TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef );
96 bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
98 else
100 nArgCount = 1;
101 ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) );
102 pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
103 pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
104 pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
105 pbIsIn[0] = sal_True;
106 pbIsOut[0] = sal_False;
107 ppArgType[0] = 0;
108 TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef );
109 pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] );
112 if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass )
114 pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType;
115 TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef );
116 bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
117 nArgCount = pMethodType->nParams;
118 ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount );
119 pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
120 pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
121 pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
123 for( i = 0 ; i < nArgCount ; i ++ )
125 ppArgType[i] = 0;
126 TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef );
127 pbIsIn[i] = pMethodType->pParams[i].bIn;
128 pbIsOut[i] = pMethodType->pParams[i].bOut;
129 pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] );
133 // create Mapping
135 void *pUnoReturn = 0;
136 void **ppUnoArgs = 0;
138 if( pReturnType )
140 if( bConversionNeededForReturn )
142 pUnoReturn = alloca( pReturnType->nSize );
144 else
146 pUnoReturn = pReturn;
150 ppUnoArgs = (void **) alloca( nArgCount * sizeof( void * ) );
151 for( i = 0 ; i < nArgCount ; i ++ )
153 if( pbConversionNeeded[i] )
155 ppUnoArgs[i] = alloca( ppArgType[i]->nSize );
156 if( pbIsIn[i] )
158 uno_copyAndConvertData(
159 ppUnoArgs[i],
160 ppArgs[i],
161 ppArgType[i],
162 p->m_mapRemote2Uno.get()
166 else
168 ppUnoArgs[i] = ppArgs[i];
172 // do the call
173 uno_Any any;
174 uno_Any *pAny = &any;
176 p->m_pUnoI->pDispatcher( p->m_pUnoI,
177 pType,
178 pUnoReturn,
179 ppUnoArgs,
180 &pAny);
182 if( ! pAny )
184 // ------------------
185 // No Exception
186 // ------------------
188 // Map return value
189 if( pReturnType && bConversionNeededForReturn )
191 uno_copyAndConvertData(
192 pReturn ,
193 pUnoReturn,
194 pReturnType,
195 p->m_mapUno2Remote.get() );
196 uno_destructData( pUnoReturn , pReturnType, 0 );
199 // map arguments
200 for( i = 0 ; i < nArgCount ; i ++ )
202 if( pbConversionNeeded[i] )
204 if( pbIsIn[i] ) {
205 if( pbIsOut[i] ) {
206 uno_destructData(
207 ppArgs[i] ,
208 ppArgType[i] ,
209 remote_release );
210 uno_copyAndConvertData( ppArgs[i] ,
211 ppUnoArgs[i],
212 ppArgType[i],
213 p->m_mapUno2Remote.get() );
216 else // pure out
218 uno_copyAndConvertData( ppArgs[i] ,
219 ppUnoArgs[i],
220 ppArgType[i],
221 p->m_mapUno2Remote.get() );
223 uno_destructData( ppUnoArgs[i],
224 ppArgType[i],
225 0 );
228 *ppException = 0;
230 else
232 // -----------------------
233 // an exception occured
234 // -----------------------
235 typelib_TypeDescription *pAnyType = 0;
236 getCppuType( (Any*) 0 ).getDescription( &pAnyType );
237 uno_copyAndConvertData( *ppException ,
238 pAny ,
239 pAnyType,
240 p->m_mapUno2Remote.get() );
241 uno_destructData( pAny , pAnyType , 0 );
242 typelib_typedescription_release( pAnyType );
244 // destruct uno in parameters ( out parameters have not been constructed )
245 for( i = 0 ; i < nArgCount ; i ++ )
247 if( pbConversionNeeded[i] && pbIsIn[i] )
249 uno_destructData( ppUnoArgs[i],
250 ppArgType[i],
251 0 );
256 //--------------------------
257 // release all acquired types
258 //--------------------------
259 if( pReturnType )
261 TYPELIB_DANGER_RELEASE( pReturnType );
263 for( i = 0 ; i < nArgCount ; i ++ )
265 TYPELIB_DANGER_RELEASE( ppArgType[ i] );
271 namespace bridges_remote {
273 void acquireUno2RemoteStub( remote_Interface *pThis )
275 Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis;
276 if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
279 p->m_pEnvRemote->pExtEnv->registerProxyInterface(
280 p->m_pEnvRemote->pExtEnv,
281 (void**)&pThis,
282 freeUno2RemoteStub,
283 p->m_sOid.pData,
284 p->m_pType );
286 OSL_ASSERT( (remote_Interface*) p == pThis );
290 void freeUno2RemoteStub(uno_ExtEnvironment *, void * stub) {
291 delete static_cast< Uno2RemoteStub * >(stub);
294 Uno2RemoteStub::Uno2RemoteStub( uno_Interface *pUnoI,
295 rtl_uString *pOid,
296 typelib_InterfaceTypeDescription *pType,
297 uno_Environment *pEnvUno,
298 uno_Environment *pEnvRemote ) :
299 m_sOid( pOid ),
300 m_pType( pType ),
301 m_pUnoI( pUnoI ),
302 m_nRef( 1 ),
303 m_pEnvUno( pEnvUno ),
304 m_pEnvRemote( pEnvRemote ),
305 m_mapRemote2Uno( pEnvRemote, pEnvUno ),
306 m_mapUno2Remote( pEnvUno, pEnvRemote )
308 typelib_typedescription_acquire( (typelib_TypeDescription * )m_pType );
309 m_pEnvUno->acquire( m_pEnvUno );
310 m_pEnvRemote->acquire( m_pEnvRemote );
312 acquire = acquireUno2RemoteStub;
313 release = thisRelease;
314 pDispatcher = thisDispatch;
316 m_pEnvUno->pExtEnv->registerInterface( m_pEnvUno->pExtEnv,
317 (void **)&m_pUnoI,
318 m_sOid.pData,
319 m_pType );
320 m_pUnoI->acquire( m_pUnoI );
321 #if OSL_DEBUG_LEVEL > 1
322 thisCounter.acquire();
323 #endif
326 Uno2RemoteStub::~Uno2RemoteStub()
328 m_pEnvUno->pExtEnv->revokeInterface( m_pEnvUno->pExtEnv , m_pUnoI );
330 typelib_typedescription_release( (typelib_TypeDescription * )m_pType );
331 m_pUnoI->release( m_pUnoI );
332 m_pEnvUno->release( m_pEnvUno );
333 m_pEnvRemote->release( m_pEnvRemote );
334 #if OSL_DEBUG_LEVEL > 1
335 thisCounter.release();
336 #endif
339 } // end namespace bridges_remote