1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2011 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include "sal/config.h" 29*cdf0e10cSrcweir 30*cdf0e10cSrcweir #include <exception> 31*cdf0e10cSrcweir #include <vector> 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx" 34*cdf0e10cSrcweir #include "osl/diagnose.h" 35*cdf0e10cSrcweir #include "rtl/ref.hxx" 36*cdf0e10cSrcweir #include "rtl/ustring.hxx" 37*cdf0e10cSrcweir #include "sal/types.h" 38*cdf0e10cSrcweir #include "typelib/typedescription.h" 39*cdf0e10cSrcweir #include "typelib/typedescription.hxx" 40*cdf0e10cSrcweir #include "uno/any2.h" 41*cdf0e10cSrcweir #include "uno/dispatcher.h" 42*cdf0e10cSrcweir #include "uno/dispatcher.hxx" 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir #include "binaryany.hxx" 45*cdf0e10cSrcweir #include "bridge.hxx" 46*cdf0e10cSrcweir #include "proxy.hxx" 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir namespace binaryurp { 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir namespace { 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir namespace css = com::sun::star; 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir extern "C" void SAL_CALL proxy_acquireInterface(uno_Interface * pInterface) { 55*cdf0e10cSrcweir OSL_ASSERT(pInterface != 0); 56*cdf0e10cSrcweir static_cast< Proxy * >(pInterface)->do_acquire(); 57*cdf0e10cSrcweir } 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir extern "C" void SAL_CALL proxy_releaseInterface(uno_Interface * pInterface) { 60*cdf0e10cSrcweir OSL_ASSERT(pInterface != 0); 61*cdf0e10cSrcweir static_cast< Proxy * >(pInterface)->do_release(); 62*cdf0e10cSrcweir } 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir extern "C" void SAL_CALL proxy_dispatchInterface( 65*cdf0e10cSrcweir uno_Interface * pUnoI, typelib_TypeDescription const * pMemberType, 66*cdf0e10cSrcweir void * pReturn, void ** pArgs, uno_Any ** ppException) 67*cdf0e10cSrcweir { 68*cdf0e10cSrcweir OSL_ASSERT(pUnoI != 0); 69*cdf0e10cSrcweir static_cast< Proxy * >(pUnoI)->do_dispatch( 70*cdf0e10cSrcweir pMemberType, pReturn, pArgs, ppException); 71*cdf0e10cSrcweir } 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir } 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir Proxy::Proxy( 76*cdf0e10cSrcweir rtl::Reference< Bridge > const & bridge, rtl::OUString const & oid, 77*cdf0e10cSrcweir css::uno::TypeDescription const & type): 78*cdf0e10cSrcweir bridge_(bridge), oid_(oid), type_(type), references_(1) 79*cdf0e10cSrcweir { 80*cdf0e10cSrcweir OSL_ASSERT(bridge.is()); 81*cdf0e10cSrcweir acquire = &proxy_acquireInterface; 82*cdf0e10cSrcweir release = &proxy_releaseInterface; 83*cdf0e10cSrcweir pDispatcher = &proxy_dispatchInterface; 84*cdf0e10cSrcweir } 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir rtl::OUString Proxy::getOid() const { 87*cdf0e10cSrcweir return oid_; 88*cdf0e10cSrcweir } 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir css::uno::TypeDescription Proxy::getType() const { 91*cdf0e10cSrcweir return type_; 92*cdf0e10cSrcweir } 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir void Proxy::do_acquire() { 95*cdf0e10cSrcweir if (osl_incrementInterlockedCount(&references_) == 1) { 96*cdf0e10cSrcweir bridge_->resurrectProxy(*this); 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir } 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir void Proxy::do_release() { 101*cdf0e10cSrcweir if (osl_decrementInterlockedCount(&references_) == 0) { 102*cdf0e10cSrcweir bridge_->revokeProxy(*this); 103*cdf0e10cSrcweir } 104*cdf0e10cSrcweir } 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir void Proxy::do_free() { 107*cdf0e10cSrcweir bridge_->freeProxy(*this); 108*cdf0e10cSrcweir delete this; 109*cdf0e10cSrcweir } 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir void Proxy::do_dispatch( 112*cdf0e10cSrcweir typelib_TypeDescription const * member, void * returnValue, 113*cdf0e10cSrcweir void ** arguments, uno_Any ** exception) const 114*cdf0e10cSrcweir { 115*cdf0e10cSrcweir try { 116*cdf0e10cSrcweir try { 117*cdf0e10cSrcweir do_dispatch_throw(member, returnValue, arguments, exception); 118*cdf0e10cSrcweir } catch (std::exception & e) { 119*cdf0e10cSrcweir throw css::uno::RuntimeException( 120*cdf0e10cSrcweir (rtl::OUString( 121*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("caught C++ exception: ")) + 122*cdf0e10cSrcweir rtl::OStringToOUString( 123*cdf0e10cSrcweir rtl::OString(e.what()), RTL_TEXTENCODING_ASCII_US)), 124*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface >()); 125*cdf0e10cSrcweir // best-effort string conversion 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir } catch (css::uno::RuntimeException &) { 128*cdf0e10cSrcweir css::uno::Any exc(cppu::getCaughtException()); 129*cdf0e10cSrcweir uno_copyAndConvertData( 130*cdf0e10cSrcweir *exception, &exc, 131*cdf0e10cSrcweir (css::uno::TypeDescription(cppu::UnoType< css::uno::Any >::get()). 132*cdf0e10cSrcweir get()), 133*cdf0e10cSrcweir bridge_->getCppToBinaryMapping().get()); 134*cdf0e10cSrcweir } 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir bool Proxy::isProxy( 138*cdf0e10cSrcweir rtl::Reference< Bridge > const & bridge, 139*cdf0e10cSrcweir css::uno::UnoInterfaceReference const & object, rtl::OUString * oid) 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir OSL_ASSERT(object.is()); 142*cdf0e10cSrcweir return object.m_pUnoI->acquire == &proxy_acquireInterface && 143*cdf0e10cSrcweir static_cast< Proxy * >(object.m_pUnoI)->isProxy(bridge, oid); 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir Proxy::~Proxy() {} 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir void Proxy::do_dispatch_throw( 149*cdf0e10cSrcweir typelib_TypeDescription const * member, void * returnValue, 150*cdf0e10cSrcweir void ** arguments, uno_Any ** exception) const 151*cdf0e10cSrcweir { 152*cdf0e10cSrcweir //TODO: Optimize queryInterface: 153*cdf0e10cSrcweir OSL_ASSERT(member != 0); 154*cdf0e10cSrcweir bool setter = false; 155*cdf0e10cSrcweir std::vector< BinaryAny > inArgs; 156*cdf0e10cSrcweir switch (member->eTypeClass) { 157*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_ATTRIBUTE: 158*cdf0e10cSrcweir setter = returnValue == 0; 159*cdf0e10cSrcweir if (setter) { 160*cdf0e10cSrcweir inArgs.push_back( 161*cdf0e10cSrcweir BinaryAny( 162*cdf0e10cSrcweir css::uno::TypeDescription( 163*cdf0e10cSrcweir reinterpret_cast< 164*cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription const * >( 165*cdf0e10cSrcweir member)-> 166*cdf0e10cSrcweir pAttributeTypeRef), 167*cdf0e10cSrcweir arguments[0])); 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir break; 170*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_METHOD: 171*cdf0e10cSrcweir { 172*cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription const * mtd = 173*cdf0e10cSrcweir reinterpret_cast< 174*cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription const * >(member); 175*cdf0e10cSrcweir for (sal_Int32 i = 0; i != mtd->nParams; ++i) { 176*cdf0e10cSrcweir if (mtd->pParams[i].bIn) { 177*cdf0e10cSrcweir inArgs.push_back( 178*cdf0e10cSrcweir BinaryAny( 179*cdf0e10cSrcweir css::uno::TypeDescription(mtd->pParams[i].pTypeRef), 180*cdf0e10cSrcweir arguments[i])); 181*cdf0e10cSrcweir } 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir break; 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir default: 186*cdf0e10cSrcweir OSL_ASSERT(false); // this cannot happen 187*cdf0e10cSrcweir break; 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir BinaryAny ret; 190*cdf0e10cSrcweir std::vector< BinaryAny > outArgs; 191*cdf0e10cSrcweir if (bridge_->makeCall( 192*cdf0e10cSrcweir oid_, 193*cdf0e10cSrcweir css::uno::TypeDescription( 194*cdf0e10cSrcweir const_cast< typelib_TypeDescription * >(member)), 195*cdf0e10cSrcweir setter, inArgs, &ret, &outArgs)) 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir OSL_ASSERT( 198*cdf0e10cSrcweir ret.getType().get()->eTypeClass == typelib_TypeClass_EXCEPTION); 199*cdf0e10cSrcweir uno_any_construct( 200*cdf0e10cSrcweir *exception, ret.getValue(ret.getType()), ret.getType().get(), 0); 201*cdf0e10cSrcweir } else { 202*cdf0e10cSrcweir switch (member->eTypeClass) { 203*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_ATTRIBUTE: 204*cdf0e10cSrcweir if (!setter) { 205*cdf0e10cSrcweir css::uno::TypeDescription t( 206*cdf0e10cSrcweir reinterpret_cast< 207*cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription const * >( 208*cdf0e10cSrcweir member)-> 209*cdf0e10cSrcweir pAttributeTypeRef); 210*cdf0e10cSrcweir uno_copyData(returnValue, ret.getValue(t), t.get(), 0); 211*cdf0e10cSrcweir } 212*cdf0e10cSrcweir break; 213*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_METHOD: 214*cdf0e10cSrcweir { 215*cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription const * mtd = 216*cdf0e10cSrcweir reinterpret_cast< 217*cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription const * >( 218*cdf0e10cSrcweir member); 219*cdf0e10cSrcweir css::uno::TypeDescription t(mtd->pReturnTypeRef); 220*cdf0e10cSrcweir if (t.get()->eTypeClass != typelib_TypeClass_VOID) { 221*cdf0e10cSrcweir uno_copyData(returnValue, ret.getValue(t), t.get(), 0); 222*cdf0e10cSrcweir } 223*cdf0e10cSrcweir std::vector< BinaryAny >::iterator i(outArgs.begin()); 224*cdf0e10cSrcweir for (sal_Int32 j = 0; j != mtd->nParams; ++j) { 225*cdf0e10cSrcweir if (mtd->pParams[j].bOut) { 226*cdf0e10cSrcweir css::uno::TypeDescription pt(mtd->pParams[j].pTypeRef); 227*cdf0e10cSrcweir if (mtd->pParams[j].bIn) { 228*cdf0e10cSrcweir uno_assignData( 229*cdf0e10cSrcweir arguments[j], pt.get(), i++->getValue(pt), 230*cdf0e10cSrcweir pt.get(), 0, 0, 0); 231*cdf0e10cSrcweir } else { 232*cdf0e10cSrcweir uno_copyData( 233*cdf0e10cSrcweir arguments[j], i++->getValue(pt), pt.get(), 0); 234*cdf0e10cSrcweir } 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir } 237*cdf0e10cSrcweir OSL_ASSERT(i == outArgs.end()); 238*cdf0e10cSrcweir break; 239*cdf0e10cSrcweir } 240*cdf0e10cSrcweir default: 241*cdf0e10cSrcweir OSL_ASSERT(false); // this cannot happen 242*cdf0e10cSrcweir break; 243*cdf0e10cSrcweir } 244*cdf0e10cSrcweir *exception = 0; 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir } 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir bool Proxy::isProxy( 249*cdf0e10cSrcweir rtl::Reference< Bridge > const & bridge, rtl::OUString * oid) const 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir OSL_ASSERT(oid != 0); 252*cdf0e10cSrcweir if (bridge == bridge_) { 253*cdf0e10cSrcweir *oid = oid_; 254*cdf0e10cSrcweir return true; 255*cdf0e10cSrcweir } else { 256*cdf0e10cSrcweir return false; 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir } 259*cdf0e10cSrcweir 260*cdf0e10cSrcweir } 261