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 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 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 = ¶m; 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 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" { 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 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 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 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 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 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 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 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 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 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" { 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 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 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