1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: proxy.cxx,v $
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
39 #include <sal/alloca.h>
40 #include <bridges/remote/proxy.hxx>
41 #include <bridges/remote/context.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");
58 using namespace ::bridges_remote
;
59 using namespace ::com::sun::star::uno
;
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
,
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
,
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
;
128 TYPELIB_DANGER_GET( &pReturnType
, pAttributeType
->pAttributeTypeRef
);
129 bConversionNeededForReturn
= remote_relatesToInterface( pReturnType
);
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
;
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
);
158 for( i
= 0 ; i
< nArgCount
; i
++ )
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;
171 if( bConversionNeededForReturn
)
173 pRemoteReturn
= alloca( pReturnType
->nSize
);
177 pRemoteReturn
= pReturn
;
181 void ** ppRemoteArgs
= 0;
184 ppRemoteArgs
= (void**) alloca( sizeof( void * ) * nArgCount
);
188 for( i
= 0 ; i
< nArgCount
; i
++ )
190 if( pbConversionNeeded
[i
] )
192 ppRemoteArgs
[i
] = alloca( ppArgType
[i
]->nSize
);
195 uno_copyAndConvertData(
199 p
->m_mapUno2Remote
.get() );
204 ppRemoteArgs
[i
] = ppArgs
[i
];
209 uno_Any
*pAny
= &any
;
211 p
->m_pRemoteI
->pDispatcher( p
->m_pRemoteI
,
219 if( pReturn
&& bConversionNeededForReturn
)
221 uno_copyAndConvertData(
225 p
->m_mapRemote2Uno
.get() );
226 uno_destructData( pRemoteReturn
, pReturnType
, remote_release
);
230 for( j
= 0 ; j
< nArgCount
; j
++ )
232 if( pbConversionNeeded
[j
] )
236 uno_destructData( ppArgs
[j
] ,
239 uno_copyAndConvertData( ppArgs
[j
] ,
242 p
->m_mapRemote2Uno
.get() );
247 uno_copyAndConvertData( ppArgs
[j
] ,
250 p
->m_mapRemote2Uno
.get() );
252 uno_destructData( ppRemoteArgs
[j
],
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
,
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
],
285 //--------------------------
286 // release all acquired types
287 //--------------------------
290 TYPELIB_DANGER_RELEASE( pReturnType
);
292 for( i
= 0 ; i
< nArgCount
; i
++ )
294 TYPELIB_DANGER_RELEASE( ppArgType
[ i
] );
299 Remote2UnoProxy::Remote2UnoProxy( remote_Interface
*pRemoteI
,
301 typelib_InterfaceTypeDescription
*pType
,
302 uno_Environment
*pEnvUno
,
303 uno_Environment
*pEnvRemote
) :
306 m_pRemoteI( pRemoteI
),
307 m_pEnvUno( pEnvUno
),
308 m_pEnvRemote( pEnvRemote
),
309 m_mapRemote2Uno( pEnvRemote
, pEnvUno
),
310 m_mapUno2Remote( pEnvUno
, pEnvRemote
),
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
,
326 m_pRemoteI
->acquire( m_pRemoteI
);
328 #if OSL_DEBUG_LEVEL > 1
329 thisCounter
.acquire();
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();
347 } // end namespace bridge_remote