1*129fa3d1SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*129fa3d1SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*129fa3d1SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*129fa3d1SAndrew Rist  * distributed with this work for additional information
6*129fa3d1SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*129fa3d1SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*129fa3d1SAndrew Rist  * "License"); you may not use this file except in compliance
9*129fa3d1SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*129fa3d1SAndrew Rist  *
11*129fa3d1SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*129fa3d1SAndrew Rist  *
13*129fa3d1SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*129fa3d1SAndrew Rist  * software distributed under the License is distributed on an
15*129fa3d1SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*129fa3d1SAndrew Rist  * KIND, either express or implied.  See the License for the
17*129fa3d1SAndrew Rist  * specific language governing permissions and limitations
18*129fa3d1SAndrew Rist  * under the License.
19*129fa3d1SAndrew Rist  *
20*129fa3d1SAndrew Rist  *************************************************************/
21*129fa3d1SAndrew Rist 
22*129fa3d1SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_cppu.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "Proxy.hxx"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include "sal/alloca.h"
30cdf0e10cSrcweir #include "uno/dispatcher.h"
31cdf0e10cSrcweir #include "typelib/typedescription.hxx"
32cdf0e10cSrcweir #include "cppu/EnvDcp.hxx"
33cdf0e10cSrcweir 
34cdf0e10cSrcweir 
35cdf0e10cSrcweir //#define LOG_LIFECYCLE_Proxy
36cdf0e10cSrcweir #ifdef LOG_LIFECYCLE_Proxy
37cdf0e10cSrcweir #  include <iostream>
38cdf0e10cSrcweir #  define LOG_LIFECYCLE_Proxy_emit(x) x
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #else
41cdf0e10cSrcweir #  define LOG_LIFECYCLE_Proxy_emit(x)
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #endif
44cdf0e10cSrcweir 
45cdf0e10cSrcweir 
46cdf0e10cSrcweir using namespace com::sun::star;
47cdf0e10cSrcweir 
48cdf0e10cSrcweir 
relatesToInterface(typelib_TypeDescription * pTypeDescr)49cdf0e10cSrcweir static bool relatesToInterface(typelib_TypeDescription * pTypeDescr)
50cdf0e10cSrcweir 	SAL_THROW( () )
51cdf0e10cSrcweir {
52cdf0e10cSrcweir 	switch (pTypeDescr->eTypeClass)
53cdf0e10cSrcweir 	{
54cdf0e10cSrcweir //  	case typelib_TypeClass_TYPEDEF:
55cdf0e10cSrcweir 	case typelib_TypeClass_SEQUENCE:
56cdf0e10cSrcweir 	{
57cdf0e10cSrcweir 		switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass)
58cdf0e10cSrcweir 		{
59cdf0e10cSrcweir 		case typelib_TypeClass_INTERFACE:
60cdf0e10cSrcweir 		case typelib_TypeClass_UNION: // might relate to interface
61cdf0e10cSrcweir 		case typelib_TypeClass_ANY: // might relate to interface
62cdf0e10cSrcweir 			return true;
63cdf0e10cSrcweir 		case typelib_TypeClass_SEQUENCE:
64cdf0e10cSrcweir 		case typelib_TypeClass_STRUCT:
65cdf0e10cSrcweir 		case typelib_TypeClass_EXCEPTION:
66cdf0e10cSrcweir 		{
67cdf0e10cSrcweir 			typelib_TypeDescription * pTD = 0;
68cdf0e10cSrcweir 			TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
69cdf0e10cSrcweir 			bool bRel = relatesToInterface( pTD );
70cdf0e10cSrcweir 			TYPELIB_DANGER_RELEASE( pTD );
71cdf0e10cSrcweir 			return bRel;
72cdf0e10cSrcweir 		}
73cdf0e10cSrcweir         default:
74cdf0e10cSrcweir             ;
75cdf0e10cSrcweir 		}
76cdf0e10cSrcweir 		return false;
77cdf0e10cSrcweir 	}
78cdf0e10cSrcweir 	case typelib_TypeClass_STRUCT:
79cdf0e10cSrcweir 	case typelib_TypeClass_EXCEPTION:
80cdf0e10cSrcweir 	{
81cdf0e10cSrcweir 		// ...optimized... to avoid getDescription() calls!
82cdf0e10cSrcweir 		typelib_CompoundTypeDescription * pComp    = (typelib_CompoundTypeDescription *)pTypeDescr;
83cdf0e10cSrcweir 		typelib_TypeDescriptionReference ** pTypes = pComp->ppTypeRefs;
84cdf0e10cSrcweir 		for ( sal_Int32 nPos = pComp->nMembers; nPos--; )
85cdf0e10cSrcweir 		{
86cdf0e10cSrcweir 			switch (pTypes[nPos]->eTypeClass)
87cdf0e10cSrcweir 			{
88cdf0e10cSrcweir 			case typelib_TypeClass_INTERFACE:
89cdf0e10cSrcweir 			case typelib_TypeClass_UNION: // might relate to interface
90cdf0e10cSrcweir 			case typelib_TypeClass_ANY: // might relate to interface
91cdf0e10cSrcweir 				return true;
92cdf0e10cSrcweir //  			case typelib_TypeClass_TYPEDEF:
93cdf0e10cSrcweir 			case typelib_TypeClass_SEQUENCE:
94cdf0e10cSrcweir 			case typelib_TypeClass_STRUCT:
95cdf0e10cSrcweir 			case typelib_TypeClass_EXCEPTION:
96cdf0e10cSrcweir 			{
97cdf0e10cSrcweir 				typelib_TypeDescription * pTD = 0;
98cdf0e10cSrcweir 				TYPELIB_DANGER_GET( &pTD, pTypes[nPos] );
99cdf0e10cSrcweir 				bool bRel = relatesToInterface( pTD );
100cdf0e10cSrcweir 				TYPELIB_DANGER_RELEASE( pTD );
101cdf0e10cSrcweir 				if (bRel)
102cdf0e10cSrcweir 					return true;
103cdf0e10cSrcweir 			}
104cdf0e10cSrcweir             default:
105cdf0e10cSrcweir                 ;
106cdf0e10cSrcweir 			}
107cdf0e10cSrcweir 		}
108cdf0e10cSrcweir 		if (pComp->pBaseTypeDescription)
109cdf0e10cSrcweir 			return relatesToInterface( (typelib_TypeDescription *)pComp->pBaseTypeDescription );
110cdf0e10cSrcweir 		break;
111cdf0e10cSrcweir 	}
112cdf0e10cSrcweir 	case typelib_TypeClass_UNION: // might relate to interface
113cdf0e10cSrcweir 	case typelib_TypeClass_ANY: // might relate to interface
114cdf0e10cSrcweir 	case typelib_TypeClass_INTERFACE:
115cdf0e10cSrcweir 		return true;
116cdf0e10cSrcweir 
117cdf0e10cSrcweir     default:
118cdf0e10cSrcweir         ;
119cdf0e10cSrcweir 	}
120cdf0e10cSrcweir 	return false;
121cdf0e10cSrcweir }
122cdf0e10cSrcweir 
s_Proxy_dispatch(uno_Interface * pUnoI,typelib_TypeDescription const * pMemberType,void * pReturn,void * pArgs[],uno_Any ** ppException)123cdf0e10cSrcweir extern "C" { static void SAL_CALL s_Proxy_dispatch(
124cdf0e10cSrcweir     uno_Interface                 * pUnoI,
125cdf0e10cSrcweir     typelib_TypeDescription const * pMemberType,
126cdf0e10cSrcweir     void                          * pReturn,
127cdf0e10cSrcweir     void                          * pArgs[],
128cdf0e10cSrcweir     uno_Any                      ** ppException)
129cdf0e10cSrcweir 	SAL_THROW_EXTERN_C()
130cdf0e10cSrcweir {
131cdf0e10cSrcweir     Proxy * pThis = static_cast<Proxy *>(pUnoI);
132cdf0e10cSrcweir 
133cdf0e10cSrcweir     typelib_MethodParameter            param;
134cdf0e10cSrcweir     sal_Int32                          nParams = 0;
135cdf0e10cSrcweir     typelib_MethodParameter          * pParams = 0;
136cdf0e10cSrcweir     typelib_TypeDescriptionReference * pReturnTypeRef = 0;
137cdf0e10cSrcweir     // sal_Int32                          nOutParams = 0;
138cdf0e10cSrcweir 
139cdf0e10cSrcweir     switch (pMemberType->eTypeClass)
140cdf0e10cSrcweir     {
141cdf0e10cSrcweir     case typelib_TypeClass_INTERFACE_ATTRIBUTE:
142cdf0e10cSrcweir         if (pReturn)
143cdf0e10cSrcweir         {
144cdf0e10cSrcweir             pReturnTypeRef =
145cdf0e10cSrcweir                 ((typelib_InterfaceAttributeTypeDescription *)
146cdf0e10cSrcweir                  pMemberType)->pAttributeTypeRef;
147cdf0e10cSrcweir             nParams = 0;
148cdf0e10cSrcweir             pParams = NULL;
149cdf0e10cSrcweir         }
150cdf0e10cSrcweir         else
151cdf0e10cSrcweir         {
152cdf0e10cSrcweir             param.pTypeRef = ((typelib_InterfaceAttributeTypeDescription *)
153cdf0e10cSrcweir                               pMemberType)->pAttributeTypeRef;
154cdf0e10cSrcweir             param.bIn = sal_True;
155cdf0e10cSrcweir             param.bOut = sal_False;
156cdf0e10cSrcweir             nParams = 1;
157cdf0e10cSrcweir             pParams = &param;
158cdf0e10cSrcweir         }
159cdf0e10cSrcweir         break;
160cdf0e10cSrcweir     case typelib_TypeClass_INTERFACE_METHOD:
161cdf0e10cSrcweir     {
162cdf0e10cSrcweir         typelib_InterfaceMethodTypeDescription * method_td =
163cdf0e10cSrcweir             (typelib_InterfaceMethodTypeDescription *) pMemberType;
164cdf0e10cSrcweir         pReturnTypeRef = method_td->pReturnTypeRef;
165cdf0e10cSrcweir         nParams = method_td->nParams;
166cdf0e10cSrcweir         pParams = method_td->pParams;
167cdf0e10cSrcweir         break;
168cdf0e10cSrcweir     }
169cdf0e10cSrcweir     default:
170cdf0e10cSrcweir         OSL_ENSURE( sal_False, "### illegal member typeclass!" );
171cdf0e10cSrcweir         abort();
172cdf0e10cSrcweir     }
173cdf0e10cSrcweir 
174cdf0e10cSrcweir     pThis->dispatch( pReturnTypeRef,
175cdf0e10cSrcweir                      pParams,
176cdf0e10cSrcweir                      nParams,
177cdf0e10cSrcweir                      pMemberType,
178cdf0e10cSrcweir                      pReturn,
179cdf0e10cSrcweir                      pArgs,
180cdf0e10cSrcweir                      ppException );
181cdf0e10cSrcweir }}
182cdf0e10cSrcweir 
Proxy_free(uno_ExtEnvironment *,void * pProxy)183cdf0e10cSrcweir extern "C" void SAL_CALL Proxy_free(uno_ExtEnvironment * /*pEnv*/, void * pProxy) SAL_THROW_EXTERN_C()
184cdf0e10cSrcweir {
185cdf0e10cSrcweir     Proxy * pThis = static_cast<Proxy * >(reinterpret_cast<uno_Interface *>(pProxy));
186cdf0e10cSrcweir 	delete pThis;
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir extern "C" {
s_Proxy_acquire(uno_Interface * pUnoI)190cdf0e10cSrcweir static void SAL_CALL s_Proxy_acquire(uno_Interface * pUnoI) SAL_THROW_EXTERN_C()
191cdf0e10cSrcweir {
192cdf0e10cSrcweir 	Proxy * pProxy = static_cast<Proxy *>(pUnoI);
193cdf0e10cSrcweir 	pProxy->acquire();
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
s_Proxy_release(uno_Interface * pUnoI)196cdf0e10cSrcweir static void SAL_CALL s_Proxy_release(uno_Interface * pUnoI) SAL_THROW_EXTERN_C()
197cdf0e10cSrcweir {
198cdf0e10cSrcweir 	Proxy * pProxy = static_cast<Proxy *>(pUnoI);
199cdf0e10cSrcweir 	pProxy->release();
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
s_acquireAndRegister_v(va_list * pParam)202cdf0e10cSrcweir static void s_acquireAndRegister_v(va_list * pParam)
203cdf0e10cSrcweir {
204cdf0e10cSrcweir 	uno_Interface                    * pUnoI      = va_arg(*pParam, uno_Interface *);
205cdf0e10cSrcweir 	rtl_uString                      * pOid       = va_arg(*pParam, rtl_uString *);
206cdf0e10cSrcweir 	typelib_InterfaceTypeDescription * pTypeDescr = va_arg(*pParam, typelib_InterfaceTypeDescription *);
207cdf0e10cSrcweir 	uno_ExtEnvironment               * pEnv       = va_arg(*pParam, uno_ExtEnvironment *);
208cdf0e10cSrcweir 
209cdf0e10cSrcweir 	pUnoI->acquire(pUnoI);
210cdf0e10cSrcweir  	pEnv->registerInterface(pEnv, reinterpret_cast<void **>(&pUnoI), pOid, pTypeDescr);
211cdf0e10cSrcweir }
212cdf0e10cSrcweir }
213cdf0e10cSrcweir 
Proxy(uno::Mapping const & to_from,uno_Environment * pTo,uno_Environment * pFrom,uno_Interface * pUnoI,typelib_InterfaceTypeDescription * pTypeDescr,rtl::OUString const & rOId,cppu::helper::purpenv::ProbeFun * probeFun,void * pProbeContext)214cdf0e10cSrcweir Proxy::Proxy(uno::Mapping                  const & to_from,
215cdf0e10cSrcweir 			 uno_Environment                     * pTo,
216cdf0e10cSrcweir 			 uno_Environment                     * pFrom,
217cdf0e10cSrcweir 			 uno_Interface                       * pUnoI,
218cdf0e10cSrcweir 			 typelib_InterfaceTypeDescription    * pTypeDescr,
219cdf0e10cSrcweir 			 rtl::OUString                 const & rOId,
220cdf0e10cSrcweir 			 cppu::helper::purpenv::ProbeFun     * probeFun,
221cdf0e10cSrcweir 			 void                                * pProbeContext
222cdf0e10cSrcweir )
223cdf0e10cSrcweir     SAL_THROW(())
224cdf0e10cSrcweir 		: m_nRef         (1),
225cdf0e10cSrcweir 		  m_from         (pFrom),
226cdf0e10cSrcweir 		  m_to           (pTo),
227cdf0e10cSrcweir 		  m_from_to      (pFrom, pTo),
228cdf0e10cSrcweir 		  m_to_from      (to_from),
229cdf0e10cSrcweir 		  m_pUnoI        (pUnoI),
230cdf0e10cSrcweir 		  m_pTypeDescr   (pTypeDescr),
231cdf0e10cSrcweir 		  m_aOId         (rOId),
232cdf0e10cSrcweir 		  m_probeFun     (probeFun),
233cdf0e10cSrcweir 		  m_pProbeContext(pProbeContext)
234cdf0e10cSrcweir {
235cdf0e10cSrcweir 	LOG_LIFECYCLE_Proxy_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Proxy::Proxy(<>)", this));
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     typelib_typedescription_acquire((typelib_TypeDescription *)m_pTypeDescr);
238cdf0e10cSrcweir     if (!((typelib_TypeDescription *)m_pTypeDescr)->bComplete)
239cdf0e10cSrcweir 		typelib_typedescription_complete((typelib_TypeDescription **)&m_pTypeDescr);
240cdf0e10cSrcweir 
241cdf0e10cSrcweir     OSL_ENSURE(((typelib_TypeDescription *)m_pTypeDescr)->bComplete, "### type is incomplete!");
242cdf0e10cSrcweir 
243cdf0e10cSrcweir 	uno_Environment_invoke(m_to.get(), s_acquireAndRegister_v, m_pUnoI, rOId.pData, pTypeDescr, m_to.get());
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 	// uno_Interface
246cdf0e10cSrcweir     uno_Interface::acquire     = s_Proxy_acquire;
247cdf0e10cSrcweir     uno_Interface::release     = s_Proxy_release;
248cdf0e10cSrcweir     uno_Interface::pDispatcher = s_Proxy_dispatch;
249cdf0e10cSrcweir }
250cdf0e10cSrcweir 
s_releaseAndRevoke_v(va_list * pParam)251cdf0e10cSrcweir extern "C" { static void s_releaseAndRevoke_v(va_list * pParam)
252cdf0e10cSrcweir {
253cdf0e10cSrcweir 	uno_ExtEnvironment * pEnv  = va_arg(*pParam, uno_ExtEnvironment *);
254cdf0e10cSrcweir 	uno_Interface      * pUnoI = va_arg(*pParam, uno_Interface *);
255cdf0e10cSrcweir 
256cdf0e10cSrcweir 	pEnv->revokeInterface(pEnv, reinterpret_cast<void *>(pUnoI));
257cdf0e10cSrcweir     pUnoI->release(pUnoI);
258cdf0e10cSrcweir }}
259cdf0e10cSrcweir 
~Proxy()260cdf0e10cSrcweir Proxy::~Proxy()
261cdf0e10cSrcweir {
262cdf0e10cSrcweir 	LOG_LIFECYCLE_Proxy_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Proxy::~Proxy()", this));
263cdf0e10cSrcweir 
264cdf0e10cSrcweir 	uno_Environment_invoke(m_to.get(), s_releaseAndRevoke_v, m_to.get(), m_pUnoI);
265cdf0e10cSrcweir 
266cdf0e10cSrcweir 	typelib_typedescription_release((typelib_TypeDescription *)m_pTypeDescr);
267cdf0e10cSrcweir }
268cdf0e10cSrcweir 
getAcquireMethod(void)269cdf0e10cSrcweir static uno::TypeDescription getAcquireMethod(void)
270cdf0e10cSrcweir {
271cdf0e10cSrcweir 	typelib_TypeDescriptionReference * type_XInterface =
272cdf0e10cSrcweir 		* typelib_static_type_getByTypeClass(typelib_TypeClass_INTERFACE);
273cdf0e10cSrcweir 
274cdf0e10cSrcweir     typelib_TypeDescription * pTXInterfaceDescr = 0;
275cdf0e10cSrcweir     TYPELIB_DANGER_GET    (&pTXInterfaceDescr, type_XInterface);
276cdf0e10cSrcweir     uno::TypeDescription acquire(
277cdf0e10cSrcweir         reinterpret_cast< typelib_InterfaceTypeDescription * >(
278cdf0e10cSrcweir             pTXInterfaceDescr)->ppAllMembers[1]);
279cdf0e10cSrcweir     TYPELIB_DANGER_RELEASE(pTXInterfaceDescr);
280cdf0e10cSrcweir 
281cdf0e10cSrcweir 	return acquire;
282cdf0e10cSrcweir }
283cdf0e10cSrcweir 
getReleaseMethod(void)284cdf0e10cSrcweir static uno::TypeDescription getReleaseMethod(void)
285cdf0e10cSrcweir {
286cdf0e10cSrcweir 	typelib_TypeDescriptionReference * type_XInterface =
287cdf0e10cSrcweir 		* typelib_static_type_getByTypeClass(typelib_TypeClass_INTERFACE);
288cdf0e10cSrcweir 
289cdf0e10cSrcweir     typelib_TypeDescription * pTXInterfaceDescr = 0;
290cdf0e10cSrcweir     TYPELIB_DANGER_GET    (&pTXInterfaceDescr, type_XInterface);
291cdf0e10cSrcweir     uno::TypeDescription release(
292cdf0e10cSrcweir         reinterpret_cast< typelib_InterfaceTypeDescription * >(
293cdf0e10cSrcweir             pTXInterfaceDescr)->ppAllMembers[2]);
294cdf0e10cSrcweir     TYPELIB_DANGER_RELEASE(pTXInterfaceDescr);
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     return release;
297cdf0e10cSrcweir }
298cdf0e10cSrcweir 
299cdf0e10cSrcweir static uno::TypeDescription s_acquireMethod(getAcquireMethod());
300cdf0e10cSrcweir static uno::TypeDescription s_releaseMethod(getReleaseMethod());
301cdf0e10cSrcweir 
acquire(void)302cdf0e10cSrcweir void Proxy::acquire(void)
303cdf0e10cSrcweir {
304cdf0e10cSrcweir 	if (m_probeFun)
305cdf0e10cSrcweir 		m_probeFun(true,
306cdf0e10cSrcweir 				   this,
307cdf0e10cSrcweir 				   m_pProbeContext,
308cdf0e10cSrcweir 				   *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID),
309cdf0e10cSrcweir 				   NULL,
310cdf0e10cSrcweir 				   0,
311cdf0e10cSrcweir 				   s_acquireMethod.get(),
312cdf0e10cSrcweir 				   NULL,
313cdf0e10cSrcweir 				   NULL,
314cdf0e10cSrcweir 				   NULL);
315cdf0e10cSrcweir 
316cdf0e10cSrcweir     if (osl_incrementInterlockedCount(&m_nRef) == 1)
317cdf0e10cSrcweir     {
318cdf0e10cSrcweir         // rebirth of proxy zombie
319cdf0e10cSrcweir 		void * pThis = this;
320cdf0e10cSrcweir         m_from.get()->pExtEnv->registerProxyInterface(m_from.get()->pExtEnv,
321cdf0e10cSrcweir 													  &pThis,
322cdf0e10cSrcweir 													  Proxy_free,
323cdf0e10cSrcweir 													  m_aOId.pData,
324cdf0e10cSrcweir 													  m_pTypeDescr);
325cdf0e10cSrcweir         OSL_ASSERT(pThis == this);
326cdf0e10cSrcweir     }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 	if (m_probeFun)
329cdf0e10cSrcweir 		m_probeFun(false,
330cdf0e10cSrcweir 				   this,
331cdf0e10cSrcweir 				   m_pProbeContext,
332cdf0e10cSrcweir 				   *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID),
333cdf0e10cSrcweir 				   NULL,
334cdf0e10cSrcweir 				   0,
335cdf0e10cSrcweir 				   s_acquireMethod.get(),
336cdf0e10cSrcweir 				   NULL,
337cdf0e10cSrcweir 				   NULL,
338cdf0e10cSrcweir 				   NULL);
339cdf0e10cSrcweir 
340cdf0e10cSrcweir }
341cdf0e10cSrcweir 
release(void)342cdf0e10cSrcweir void Proxy::release(void)
343cdf0e10cSrcweir {
344cdf0e10cSrcweir 	cppu::helper::purpenv::ProbeFun * probeFun = m_probeFun;
345cdf0e10cSrcweir 	void                            * pProbeContext = m_pProbeContext;
346cdf0e10cSrcweir 
347cdf0e10cSrcweir 	if (m_probeFun)
348cdf0e10cSrcweir 		m_probeFun(true,
349cdf0e10cSrcweir 				   this,
350cdf0e10cSrcweir 				   m_pProbeContext,
351cdf0e10cSrcweir 				   *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID),
352cdf0e10cSrcweir 				   NULL,
353cdf0e10cSrcweir 				   0,
354cdf0e10cSrcweir 				   s_releaseMethod.get(),
355cdf0e10cSrcweir 				   NULL,
356cdf0e10cSrcweir 				   NULL,
357cdf0e10cSrcweir 				   NULL);
358cdf0e10cSrcweir 
359cdf0e10cSrcweir     if (osl_decrementInterlockedCount(&m_nRef) == 0)
360cdf0e10cSrcweir         m_from.get()->pExtEnv->revokeInterface(m_from.get()->pExtEnv, this);
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 	if (probeFun)
363cdf0e10cSrcweir 		probeFun(false,
364cdf0e10cSrcweir 				 this,
365cdf0e10cSrcweir 				 pProbeContext,
366cdf0e10cSrcweir 				 *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID),
367cdf0e10cSrcweir 				 NULL,
368cdf0e10cSrcweir 				 0,
369cdf0e10cSrcweir 				 s_releaseMethod.get(),
370cdf0e10cSrcweir 				 NULL,
371cdf0e10cSrcweir 				 NULL,
372cdf0e10cSrcweir 				 NULL);
373cdf0e10cSrcweir 
374cdf0e10cSrcweir }
375cdf0e10cSrcweir 
376cdf0e10cSrcweir 
377cdf0e10cSrcweir extern "C" {
s_type_destructData_v(va_list * pParam)378cdf0e10cSrcweir static void s_type_destructData_v(va_list * pParam)
379cdf0e10cSrcweir {
380cdf0e10cSrcweir 	void * ret = va_arg(*pParam, void *);
381cdf0e10cSrcweir 	typelib_TypeDescriptionReference * pReturnTypeRef = va_arg(*pParam, typelib_TypeDescriptionReference *);
382cdf0e10cSrcweir 
383cdf0e10cSrcweir 	uno_type_destructData(ret, pReturnTypeRef, 0);
384cdf0e10cSrcweir }
385cdf0e10cSrcweir 
s_dispatcher_v(va_list * pParam)386cdf0e10cSrcweir static void s_dispatcher_v(va_list * pParam)
387cdf0e10cSrcweir {
388cdf0e10cSrcweir 	uno_Interface                 * pUnoI       = va_arg(*pParam, uno_Interface *);
389cdf0e10cSrcweir 	typelib_TypeDescription const * pMemberType = va_arg(*pParam, typelib_TypeDescription const *);
390cdf0e10cSrcweir 	void                          * pReturn     = va_arg(*pParam, void *);
391cdf0e10cSrcweir 	void                         ** pArgs       = va_arg(*pParam, void **);
392cdf0e10cSrcweir 	uno_Any                      ** ppException = va_arg(*pParam, uno_Any **);
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 	pUnoI->pDispatcher(pUnoI, pMemberType, pReturn, pArgs, ppException);
395cdf0e10cSrcweir }
396cdf0e10cSrcweir }
397cdf0e10cSrcweir 
dispatch(typelib_TypeDescriptionReference * pReturnTypeRef,typelib_MethodParameter * pParams,sal_Int32 nParams,typelib_TypeDescription const * pMemberType,void * pReturn,void * pArgs[],uno_Any ** ppException)398cdf0e10cSrcweir void Proxy::dispatch(typelib_TypeDescriptionReference * pReturnTypeRef,
399cdf0e10cSrcweir 					 typelib_MethodParameter          * pParams,
400cdf0e10cSrcweir 					 sal_Int32                          nParams,
401cdf0e10cSrcweir 					 typelib_TypeDescription    const * pMemberType,
402cdf0e10cSrcweir 					 void                             * pReturn,
403cdf0e10cSrcweir 					 void                             * pArgs[],
404cdf0e10cSrcweir 					 uno_Any                         ** ppException)
405cdf0e10cSrcweir {
406cdf0e10cSrcweir 	if (m_probeFun)
407cdf0e10cSrcweir 		m_probeFun(true,
408cdf0e10cSrcweir 				   this,
409cdf0e10cSrcweir 				   m_pProbeContext,
410cdf0e10cSrcweir 				   pReturnTypeRef,
411cdf0e10cSrcweir 				   pParams,
412cdf0e10cSrcweir 				   nParams,
413cdf0e10cSrcweir 				   pMemberType,
414cdf0e10cSrcweir 				   pReturn,
415cdf0e10cSrcweir 				   pArgs,
416cdf0e10cSrcweir 				   ppException);
417cdf0e10cSrcweir 
418cdf0e10cSrcweir     void ** args = (void **) alloca( sizeof (void *) * nParams );
419cdf0e10cSrcweir 
420cdf0e10cSrcweir     typelib_TypeDescription * return_td = 0;
421cdf0e10cSrcweir     void * ret = pReturn;
422cdf0e10cSrcweir 	if (pReturnTypeRef)
423cdf0e10cSrcweir 	{
424cdf0e10cSrcweir 		TYPELIB_DANGER_GET(&return_td, pReturnTypeRef);
425cdf0e10cSrcweir 
426cdf0e10cSrcweir 		if (relatesToInterface(return_td))
427cdf0e10cSrcweir 			ret = alloca(return_td->nSize);
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 		TYPELIB_DANGER_RELEASE(return_td);
430cdf0e10cSrcweir 	}
431cdf0e10cSrcweir 
432cdf0e10cSrcweir     for (sal_Int32 nPos = 0; nPos < nParams; ++ nPos)
433cdf0e10cSrcweir     {
434cdf0e10cSrcweir         typelib_MethodParameter const & param = pParams[nPos];
435cdf0e10cSrcweir         typelib_TypeDescription * td = 0;
436cdf0e10cSrcweir         TYPELIB_DANGER_GET( &td, param.pTypeRef );
437cdf0e10cSrcweir         if (relatesToInterface(td))
438cdf0e10cSrcweir         {
439cdf0e10cSrcweir             args[nPos] = alloca(td->nSize);
440cdf0e10cSrcweir             if (param.bIn)
441cdf0e10cSrcweir             {
442cdf0e10cSrcweir                 uno_copyAndConvertData(args[nPos], pArgs[nPos], td, m_from_to.get());
443cdf0e10cSrcweir             }
444cdf0e10cSrcweir         }
445cdf0e10cSrcweir         else
446cdf0e10cSrcweir         {
447cdf0e10cSrcweir             args[nPos] = pArgs[nPos];
448cdf0e10cSrcweir         }
449cdf0e10cSrcweir         TYPELIB_DANGER_RELEASE( td );
450cdf0e10cSrcweir     }
451cdf0e10cSrcweir 
452cdf0e10cSrcweir     uno_Any exc_data;
453cdf0e10cSrcweir     uno_Any * exc = &exc_data;
454cdf0e10cSrcweir 
455cdf0e10cSrcweir 	// do the UNO call...
456cdf0e10cSrcweir 	uno_Environment_invoke(m_to.get(), s_dispatcher_v, m_pUnoI, pMemberType, ret, args, &exc);
457cdf0e10cSrcweir 
458cdf0e10cSrcweir     if (exc == 0)
459cdf0e10cSrcweir     {
460cdf0e10cSrcweir         for (sal_Int32 nPos = 0; nPos < nParams; ++ nPos)
461cdf0e10cSrcweir         {
462cdf0e10cSrcweir             if (args[nPos] != pArgs[nPos])
463cdf0e10cSrcweir             {
464cdf0e10cSrcweir                 typelib_MethodParameter const & param = pParams[nPos];
465cdf0e10cSrcweir                 if (param.bOut)
466cdf0e10cSrcweir                 {
467cdf0e10cSrcweir                     if (param.bIn) // is inout
468cdf0e10cSrcweir                     {
469cdf0e10cSrcweir                         uno_type_destructData(pArgs[nPos], param.pTypeRef, 0);
470cdf0e10cSrcweir                     }
471cdf0e10cSrcweir                     uno_type_copyAndConvertData(pArgs[ nPos ],
472cdf0e10cSrcweir 												args[ nPos ],
473cdf0e10cSrcweir 												param.pTypeRef,
474cdf0e10cSrcweir 												m_to_from.get());
475cdf0e10cSrcweir                 }
476cdf0e10cSrcweir 				uno_Environment_invoke(m_to.get(), s_type_destructData_v, args[nPos], param.pTypeRef, 0);
477cdf0e10cSrcweir             }
478cdf0e10cSrcweir         }
479cdf0e10cSrcweir         if (ret != pReturn)
480cdf0e10cSrcweir         {
481cdf0e10cSrcweir             uno_type_copyAndConvertData(pReturn,
482cdf0e10cSrcweir 										ret,
483cdf0e10cSrcweir 										pReturnTypeRef,
484cdf0e10cSrcweir 										m_to_from.get());
485cdf0e10cSrcweir 
486cdf0e10cSrcweir 			uno_Environment_invoke(m_to.get(), s_type_destructData_v, ret, pReturnTypeRef, 0);
487cdf0e10cSrcweir         }
488cdf0e10cSrcweir 
489cdf0e10cSrcweir         *ppException = 0;
490cdf0e10cSrcweir     }
491cdf0e10cSrcweir     else // exception occured
492cdf0e10cSrcweir     {
493cdf0e10cSrcweir         for (sal_Int32 nPos = 0; nPos < nParams; ++ nPos)
494cdf0e10cSrcweir         {
495cdf0e10cSrcweir             if (args[nPos] != pArgs[nPos])
496cdf0e10cSrcweir             {
497cdf0e10cSrcweir                 typelib_MethodParameter const & param = pParams[nPos];
498cdf0e10cSrcweir                 if (param.bIn)
499cdf0e10cSrcweir                 {
500cdf0e10cSrcweir 					uno_Environment_invoke(m_to.get(), s_type_destructData_v, args[nPos], param.pTypeRef, 0);
501cdf0e10cSrcweir                 }
502cdf0e10cSrcweir             }
503cdf0e10cSrcweir         }
504cdf0e10cSrcweir 
505cdf0e10cSrcweir         uno_type_any_constructAndConvert(*ppException,
506cdf0e10cSrcweir 										 exc->pData,
507cdf0e10cSrcweir 										 exc->pType,
508cdf0e10cSrcweir 										 m_to_from.get());
509cdf0e10cSrcweir 
510cdf0e10cSrcweir 		// FIXME: need to destruct in m_to
511cdf0e10cSrcweir 		uno_any_destruct(exc, 0);
512cdf0e10cSrcweir     }
513cdf0e10cSrcweir 
514cdf0e10cSrcweir 	if (m_probeFun)
515cdf0e10cSrcweir 		m_probeFun(false,
516cdf0e10cSrcweir 				   this,
517cdf0e10cSrcweir 				   m_pProbeContext,
518cdf0e10cSrcweir 				   pReturnTypeRef,
519cdf0e10cSrcweir 				   pParams,
520cdf0e10cSrcweir 				   nParams,
521cdf0e10cSrcweir 				   pMemberType,
522cdf0e10cSrcweir 				   pReturn,
523cdf0e10cSrcweir 				   pArgs,
524cdf0e10cSrcweir 				   ppException);
525cdf0e10cSrcweir }
526cdf0e10cSrcweir 
527