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: stub.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 #include <sal/alloca.h>
34 #include <osl/diagnose.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");
51 using namespace ::com::sun::star::uno
;
52 using namespace bridges_remote
;
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
,
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;
82 sal_Bool
*pbIsOut
= 0;
83 sal_Bool bConversionNeededForReturn
= sal_False
;
84 sal_Bool
*pbConversionNeeded
= 0;
87 //--------------------------------
88 // Collect all needed types !
89 //--------------------------------
90 if( typelib_TypeClass_INTERFACE_ATTRIBUTE
== pType
->eTypeClass
)
92 pAttributeType
= ( typelib_InterfaceAttributeTypeDescription
* ) pType
;
95 TYPELIB_DANGER_GET( &pReturnType
, pAttributeType
->pAttributeTypeRef
);
96 bConversionNeededForReturn
= remote_relatesToInterface( pReturnType
);
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
;
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
++ )
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
] );
135 void *pUnoReturn
= 0;
136 void **ppUnoArgs
= 0;
140 if( bConversionNeededForReturn
)
142 pUnoReturn
= alloca( pReturnType
->nSize
);
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
);
158 uno_copyAndConvertData(
162 p
->m_mapRemote2Uno
.get()
168 ppUnoArgs
[i
] = ppArgs
[i
];
174 uno_Any
*pAny
= &any
;
176 p
->m_pUnoI
->pDispatcher( p
->m_pUnoI
,
184 // ------------------
186 // ------------------
189 if( pReturnType
&& bConversionNeededForReturn
)
191 uno_copyAndConvertData(
195 p
->m_mapUno2Remote
.get() );
196 uno_destructData( pUnoReturn
, pReturnType
, 0 );
200 for( i
= 0 ; i
< nArgCount
; i
++ )
202 if( pbConversionNeeded
[i
] )
210 uno_copyAndConvertData( ppArgs
[i
] ,
213 p
->m_mapUno2Remote
.get() );
218 uno_copyAndConvertData( ppArgs
[i
] ,
221 p
->m_mapUno2Remote
.get() );
223 uno_destructData( ppUnoArgs
[i
],
232 // -----------------------
233 // an exception occured
234 // -----------------------
235 typelib_TypeDescription
*pAnyType
= 0;
236 getCppuType( (Any
*) 0 ).getDescription( &pAnyType
);
237 uno_copyAndConvertData( *ppException
,
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
],
256 //--------------------------
257 // release all acquired types
258 //--------------------------
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
,
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
,
296 typelib_InterfaceTypeDescription
*pType
,
297 uno_Environment
*pEnvUno
,
298 uno_Environment
*pEnvRemote
) :
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
,
320 m_pUnoI
->acquire( m_pUnoI
);
321 #if OSL_DEBUG_LEVEL > 1
322 thisCounter
.acquire();
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();
339 } // end namespace bridges_remote