1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 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 // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_stoc.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "osl/diagnose.h" 32*cdf0e10cSrcweir #include "osl/interlck.h" 33*cdf0e10cSrcweir #include "osl/doublecheckedlocking.h" 34*cdf0e10cSrcweir #include "osl/mutex.hxx" 35*cdf0e10cSrcweir #include "rtl/ref.hxx" 36*cdf0e10cSrcweir #include "uno/dispatcher.hxx" 37*cdf0e10cSrcweir #include "uno/data.h" 38*cdf0e10cSrcweir #include "uno/mapping.hxx" 39*cdf0e10cSrcweir #include "uno/environment.hxx" 40*cdf0e10cSrcweir #include "typelib/typedescription.hxx" 41*cdf0e10cSrcweir #include "cppuhelper/exc_hlp.hxx" 42*cdf0e10cSrcweir #include "cppuhelper/implbase2.hxx" 43*cdf0e10cSrcweir #include "cppuhelper/implementationentry.hxx" 44*cdf0e10cSrcweir #include "cppuhelper/factory.hxx" 45*cdf0e10cSrcweir #include "com/sun/star/lang/XServiceInfo.hpp" 46*cdf0e10cSrcweir #include "com/sun/star/registry/XRegistryKey.hpp" 47*cdf0e10cSrcweir #include "com/sun/star/reflection/XProxyFactory.hpp" 48*cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp" 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 51*cdf0e10cSrcweir #define SERVICE_NAME "com.sun.star.reflection.ProxyFactory" 52*cdf0e10cSrcweir #define IMPL_NAME "com.sun.star.comp.reflection.ProxyFactory" 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir using namespace ::com::sun::star; 56*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 57*cdf0e10cSrcweir using ::rtl::OUString; 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir namespace 61*cdf0e10cSrcweir { 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir static OUString proxyfac_getImplementationName() 66*cdf0e10cSrcweir { 67*cdf0e10cSrcweir return OUSTR(IMPL_NAME); 68*cdf0e10cSrcweir } 69*cdf0e10cSrcweir 70*cdf0e10cSrcweir static Sequence< OUString > proxyfac_getSupportedServiceNames() 71*cdf0e10cSrcweir { 72*cdf0e10cSrcweir OUString str_name = OUSTR(SERVICE_NAME); 73*cdf0e10cSrcweir return Sequence< OUString >( &str_name, 1 ); 74*cdf0e10cSrcweir } 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir //============================================================================== 77*cdf0e10cSrcweir struct FactoryImpl : public ::cppu::WeakImplHelper2< lang::XServiceInfo, 78*cdf0e10cSrcweir reflection::XProxyFactory > 79*cdf0e10cSrcweir { 80*cdf0e10cSrcweir Environment m_uno_env; 81*cdf0e10cSrcweir Environment m_cpp_env; 82*cdf0e10cSrcweir Mapping m_uno2cpp; 83*cdf0e10cSrcweir Mapping m_cpp2uno; 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir UnoInterfaceReference binuno_queryInterface( 86*cdf0e10cSrcweir UnoInterfaceReference const & unoI, 87*cdf0e10cSrcweir typelib_InterfaceTypeDescription * pTypeDescr ); 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir FactoryImpl(); 90*cdf0e10cSrcweir virtual ~FactoryImpl(); 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir // XServiceInfo 93*cdf0e10cSrcweir virtual OUString SAL_CALL getImplementationName() 94*cdf0e10cSrcweir throw (RuntimeException); 95*cdf0e10cSrcweir virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) 96*cdf0e10cSrcweir throw (RuntimeException); 97*cdf0e10cSrcweir virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() 98*cdf0e10cSrcweir throw (RuntimeException); 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir // XProxyFactory 101*cdf0e10cSrcweir virtual Reference< XAggregation > SAL_CALL createProxy( 102*cdf0e10cSrcweir Reference< XInterface > const & xTarget ) 103*cdf0e10cSrcweir throw (RuntimeException); 104*cdf0e10cSrcweir }; 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir //______________________________________________________________________________ 107*cdf0e10cSrcweir UnoInterfaceReference FactoryImpl::binuno_queryInterface( 108*cdf0e10cSrcweir UnoInterfaceReference const & unoI, 109*cdf0e10cSrcweir typelib_InterfaceTypeDescription * pTypeDescr ) 110*cdf0e10cSrcweir { 111*cdf0e10cSrcweir // init queryInterface() td 112*cdf0e10cSrcweir static typelib_TypeDescription * s_pQITD = 0; 113*cdf0e10cSrcweir if (s_pQITD == 0) 114*cdf0e10cSrcweir { 115*cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 116*cdf0e10cSrcweir if (s_pQITD == 0) 117*cdf0e10cSrcweir { 118*cdf0e10cSrcweir typelib_TypeDescription * pTXInterfaceDescr = 0; 119*cdf0e10cSrcweir TYPELIB_DANGER_GET( 120*cdf0e10cSrcweir &pTXInterfaceDescr, 121*cdf0e10cSrcweir ::getCppuType( reinterpret_cast< Reference< XInterface > 122*cdf0e10cSrcweir const * >(0) ).getTypeLibType() ); 123*cdf0e10cSrcweir typelib_TypeDescription * pQITD = 0; 124*cdf0e10cSrcweir typelib_typedescriptionreference_getDescription( 125*cdf0e10cSrcweir &pQITD, reinterpret_cast< typelib_InterfaceTypeDescription * >( 126*cdf0e10cSrcweir pTXInterfaceDescr )->ppAllMembers[ 0 ] ); 127*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTXInterfaceDescr ); 128*cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 129*cdf0e10cSrcweir s_pQITD = pQITD; 130*cdf0e10cSrcweir } 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir else 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir void * args[ 1 ]; 138*cdf0e10cSrcweir args[ 0 ] = &reinterpret_cast< typelib_TypeDescription * >( 139*cdf0e10cSrcweir pTypeDescr )->pWeakRef; 140*cdf0e10cSrcweir uno_Any ret_val, exc_space; 141*cdf0e10cSrcweir uno_Any * exc = &exc_space; 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir unoI.dispatch( s_pQITD, &ret_val, args, &exc ); 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir if (exc == 0) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir UnoInterfaceReference ret; 148*cdf0e10cSrcweir if (ret_val.pType->eTypeClass == typelib_TypeClass_INTERFACE) 149*cdf0e10cSrcweir { 150*cdf0e10cSrcweir ret.set( *reinterpret_cast< uno_Interface ** >(ret_val.pData), 151*cdf0e10cSrcweir SAL_NO_ACQUIRE ); 152*cdf0e10cSrcweir typelib_typedescriptionreference_release( ret_val.pType ); 153*cdf0e10cSrcweir } 154*cdf0e10cSrcweir else 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir uno_any_destruct( &ret_val, 0 ); 157*cdf0e10cSrcweir } 158*cdf0e10cSrcweir return ret; 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir else 161*cdf0e10cSrcweir { 162*cdf0e10cSrcweir // exception occured: 163*cdf0e10cSrcweir OSL_ENSURE( 164*cdf0e10cSrcweir typelib_typedescriptionreference_isAssignableFrom( 165*cdf0e10cSrcweir ::getCppuType( reinterpret_cast< 166*cdf0e10cSrcweir RuntimeException const * >(0) ).getTypeLibType(), 167*cdf0e10cSrcweir exc->pType ), 168*cdf0e10cSrcweir "### RuntimeException expected!" ); 169*cdf0e10cSrcweir Any cpp_exc; 170*cdf0e10cSrcweir uno_type_copyAndConvertData( 171*cdf0e10cSrcweir &cpp_exc, exc, ::getCppuType( &cpp_exc ).getTypeLibType(), 172*cdf0e10cSrcweir m_uno2cpp.get() ); 173*cdf0e10cSrcweir uno_any_destruct( exc, 0 ); 174*cdf0e10cSrcweir ::cppu::throwException( cpp_exc ); 175*cdf0e10cSrcweir OSL_ASSERT( 0 ); // way of no return 176*cdf0e10cSrcweir return UnoInterfaceReference(); // for dummy 177*cdf0e10cSrcweir } 178*cdf0e10cSrcweir } 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir //============================================================================== 181*cdf0e10cSrcweir struct ProxyRoot : public ::cppu::OWeakAggObject 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir // XAggregation 184*cdf0e10cSrcweir virtual Any SAL_CALL queryAggregation( Type const & rType ) 185*cdf0e10cSrcweir throw (RuntimeException); 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir virtual ~ProxyRoot(); 188*cdf0e10cSrcweir inline ProxyRoot( ::rtl::Reference< FactoryImpl > const & factory, 189*cdf0e10cSrcweir Reference< XInterface > const & xTarget ); 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir ::rtl::Reference< FactoryImpl > m_factory; 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir private: 194*cdf0e10cSrcweir UnoInterfaceReference m_target; 195*cdf0e10cSrcweir }; 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir //============================================================================== 198*cdf0e10cSrcweir struct binuno_Proxy : public uno_Interface 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir oslInterlockedCount m_nRefCount; 201*cdf0e10cSrcweir ::rtl::Reference< ProxyRoot > m_root; 202*cdf0e10cSrcweir UnoInterfaceReference m_target; 203*cdf0e10cSrcweir OUString m_oid; 204*cdf0e10cSrcweir TypeDescription m_typeDescr; 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir inline binuno_Proxy( 207*cdf0e10cSrcweir ::rtl::Reference< ProxyRoot > const & root, 208*cdf0e10cSrcweir UnoInterfaceReference const & target, 209*cdf0e10cSrcweir OUString const & oid, TypeDescription const & typeDescr ); 210*cdf0e10cSrcweir }; 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir extern "C" 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir //------------------------------------------------------------------------------ 216*cdf0e10cSrcweir static void SAL_CALL binuno_proxy_free( 217*cdf0e10cSrcweir uno_ExtEnvironment * pEnv, void * pProxy ) 218*cdf0e10cSrcweir { 219*cdf0e10cSrcweir (void) pEnv; // avoid warning about unused parameter 220*cdf0e10cSrcweir binuno_Proxy * proxy = static_cast< binuno_Proxy * >( 221*cdf0e10cSrcweir reinterpret_cast< uno_Interface * >( pProxy ) ); 222*cdf0e10cSrcweir OSL_ASSERT( proxy->m_root->m_factory->m_uno_env.get()->pExtEnv == pEnv ); 223*cdf0e10cSrcweir delete proxy; 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir //------------------------------------------------------------------------------ 227*cdf0e10cSrcweir static void SAL_CALL binuno_proxy_acquire( uno_Interface * pUnoI ) 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir binuno_Proxy * that = static_cast< binuno_Proxy * >( pUnoI ); 230*cdf0e10cSrcweir if (osl_incrementInterlockedCount( &that->m_nRefCount ) == 1) 231*cdf0e10cSrcweir { 232*cdf0e10cSrcweir // rebirth of zombie 233*cdf0e10cSrcweir uno_ExtEnvironment * uno_env = 234*cdf0e10cSrcweir that->m_root->m_factory->m_uno_env.get()->pExtEnv; 235*cdf0e10cSrcweir OSL_ASSERT( uno_env != 0 ); 236*cdf0e10cSrcweir (*uno_env->registerProxyInterface)( 237*cdf0e10cSrcweir uno_env, reinterpret_cast< void ** >( &pUnoI ), binuno_proxy_free, 238*cdf0e10cSrcweir that->m_oid.pData, 239*cdf0e10cSrcweir reinterpret_cast< typelib_InterfaceTypeDescription * >( 240*cdf0e10cSrcweir that->m_typeDescr.get() ) ); 241*cdf0e10cSrcweir OSL_ASSERT( that == static_cast< binuno_Proxy * >( pUnoI ) ); 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir } 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir //------------------------------------------------------------------------------ 246*cdf0e10cSrcweir static void SAL_CALL binuno_proxy_release( uno_Interface * pUnoI ) 247*cdf0e10cSrcweir { 248*cdf0e10cSrcweir binuno_Proxy * that = static_cast< binuno_Proxy * >( pUnoI ); 249*cdf0e10cSrcweir if (osl_decrementInterlockedCount( &that->m_nRefCount ) == 0) 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir uno_ExtEnvironment * uno_env = 252*cdf0e10cSrcweir that->m_root->m_factory->m_uno_env.get()->pExtEnv; 253*cdf0e10cSrcweir OSL_ASSERT( uno_env != 0 ); 254*cdf0e10cSrcweir (*uno_env->revokeInterface)( uno_env, pUnoI ); 255*cdf0e10cSrcweir } 256*cdf0e10cSrcweir } 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir //------------------------------------------------------------------------------ 259*cdf0e10cSrcweir static void SAL_CALL binuno_proxy_dispatch( 260*cdf0e10cSrcweir uno_Interface * pUnoI, const typelib_TypeDescription * pMemberType, 261*cdf0e10cSrcweir void * pReturn, void * pArgs [], uno_Any ** ppException ) 262*cdf0e10cSrcweir { 263*cdf0e10cSrcweir binuno_Proxy * that = static_cast< binuno_Proxy * >( pUnoI ); 264*cdf0e10cSrcweir switch (reinterpret_cast< typelib_InterfaceMemberTypeDescription const * >( 265*cdf0e10cSrcweir pMemberType )->nPosition) 266*cdf0e10cSrcweir { 267*cdf0e10cSrcweir case 0: // queryInterface() 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir try 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir Type const & rType = 272*cdf0e10cSrcweir *reinterpret_cast< Type const * >( pArgs[ 0 ] ); 273*cdf0e10cSrcweir Any ret( that->m_root->queryInterface( rType ) ); 274*cdf0e10cSrcweir uno_type_copyAndConvertData( 275*cdf0e10cSrcweir pReturn, &ret, ::getCppuType( &ret ).getTypeLibType(), 276*cdf0e10cSrcweir that->m_root->m_factory->m_cpp2uno.get() ); 277*cdf0e10cSrcweir *ppException = 0; // no exc 278*cdf0e10cSrcweir } 279*cdf0e10cSrcweir catch (RuntimeException &) 280*cdf0e10cSrcweir { 281*cdf0e10cSrcweir Any exc( ::cppu::getCaughtException() ); 282*cdf0e10cSrcweir uno_type_any_constructAndConvert( 283*cdf0e10cSrcweir *ppException, const_cast< void * >(exc.getValue()), 284*cdf0e10cSrcweir exc.getValueTypeRef(), 285*cdf0e10cSrcweir that->m_root->m_factory->m_cpp2uno.get() ); 286*cdf0e10cSrcweir } 287*cdf0e10cSrcweir break; 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir case 1: // acquire() 290*cdf0e10cSrcweir binuno_proxy_acquire( pUnoI ); 291*cdf0e10cSrcweir *ppException = 0; // no exc 292*cdf0e10cSrcweir break; 293*cdf0e10cSrcweir case 2: // release() 294*cdf0e10cSrcweir binuno_proxy_release( pUnoI ); 295*cdf0e10cSrcweir *ppException = 0; // no exc 296*cdf0e10cSrcweir break; 297*cdf0e10cSrcweir default: 298*cdf0e10cSrcweir that->m_target.dispatch( pMemberType, pReturn, pArgs, ppException ); 299*cdf0e10cSrcweir break; 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir } 304*cdf0e10cSrcweir 305*cdf0e10cSrcweir //______________________________________________________________________________ 306*cdf0e10cSrcweir inline binuno_Proxy::binuno_Proxy( 307*cdf0e10cSrcweir ::rtl::Reference< ProxyRoot > const & root, 308*cdf0e10cSrcweir UnoInterfaceReference const & target, 309*cdf0e10cSrcweir OUString const & oid, TypeDescription const & typeDescr ) 310*cdf0e10cSrcweir : m_nRefCount( 1 ), 311*cdf0e10cSrcweir m_root( root ), 312*cdf0e10cSrcweir m_target( target ), 313*cdf0e10cSrcweir m_oid( oid ), 314*cdf0e10cSrcweir m_typeDescr( typeDescr ) 315*cdf0e10cSrcweir { 316*cdf0e10cSrcweir uno_Interface::acquire = binuno_proxy_acquire; 317*cdf0e10cSrcweir uno_Interface::release = binuno_proxy_release; 318*cdf0e10cSrcweir uno_Interface::pDispatcher = binuno_proxy_dispatch; 319*cdf0e10cSrcweir } 320*cdf0e10cSrcweir 321*cdf0e10cSrcweir //______________________________________________________________________________ 322*cdf0e10cSrcweir ProxyRoot::~ProxyRoot() 323*cdf0e10cSrcweir { 324*cdf0e10cSrcweir } 325*cdf0e10cSrcweir 326*cdf0e10cSrcweir //______________________________________________________________________________ 327*cdf0e10cSrcweir inline ProxyRoot::ProxyRoot( 328*cdf0e10cSrcweir ::rtl::Reference< FactoryImpl > const & factory, 329*cdf0e10cSrcweir Reference< XInterface > const & xTarget ) 330*cdf0e10cSrcweir : m_factory( factory ) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir m_factory->m_cpp2uno.mapInterface( 333*cdf0e10cSrcweir reinterpret_cast< void ** >( &m_target.m_pUnoI ), xTarget.get(), 334*cdf0e10cSrcweir ::getCppuType( &xTarget ) ); 335*cdf0e10cSrcweir OSL_ENSURE( m_target.is(), "### mapping interface failed!" ); 336*cdf0e10cSrcweir } 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir //______________________________________________________________________________ 339*cdf0e10cSrcweir Any ProxyRoot::queryAggregation( Type const & rType ) 340*cdf0e10cSrcweir throw (RuntimeException) 341*cdf0e10cSrcweir { 342*cdf0e10cSrcweir Any ret( OWeakAggObject::queryAggregation( rType ) ); 343*cdf0e10cSrcweir if (! ret.hasValue()) 344*cdf0e10cSrcweir { 345*cdf0e10cSrcweir typelib_TypeDescription * pTypeDescr = 0; 346*cdf0e10cSrcweir TYPELIB_DANGER_GET( &pTypeDescr, rType.getTypeLibType() ); 347*cdf0e10cSrcweir try 348*cdf0e10cSrcweir { 349*cdf0e10cSrcweir Reference< XInterface > xProxy; 350*cdf0e10cSrcweir uno_ExtEnvironment * cpp_env = m_factory->m_cpp_env.get()->pExtEnv; 351*cdf0e10cSrcweir OSL_ASSERT( cpp_env != 0 ); 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir // mind a new delegator, calculate current root: 354*cdf0e10cSrcweir Reference< XInterface > xRoot( 355*cdf0e10cSrcweir static_cast< OWeakObject * >(this), UNO_QUERY_THROW ); 356*cdf0e10cSrcweir OUString oid; 357*cdf0e10cSrcweir (*cpp_env->getObjectIdentifier)( cpp_env, &oid.pData, xRoot.get() ); 358*cdf0e10cSrcweir OSL_ASSERT( oid.getLength() > 0 ); 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir (*cpp_env->getRegisteredInterface)( 361*cdf0e10cSrcweir cpp_env, reinterpret_cast< void ** >( &xProxy ), 362*cdf0e10cSrcweir oid.pData, reinterpret_cast< 363*cdf0e10cSrcweir typelib_InterfaceTypeDescription * >(pTypeDescr) ); 364*cdf0e10cSrcweir if (! xProxy.is()) 365*cdf0e10cSrcweir { 366*cdf0e10cSrcweir // perform query on target: 367*cdf0e10cSrcweir UnoInterfaceReference proxy_target( 368*cdf0e10cSrcweir m_factory->binuno_queryInterface( 369*cdf0e10cSrcweir m_target, reinterpret_cast< 370*cdf0e10cSrcweir typelib_InterfaceTypeDescription * >(pTypeDescr) ) ); 371*cdf0e10cSrcweir if (proxy_target.is()) 372*cdf0e10cSrcweir { 373*cdf0e10cSrcweir // ensure root's object entries: 374*cdf0e10cSrcweir UnoInterfaceReference root; 375*cdf0e10cSrcweir m_factory->m_cpp2uno.mapInterface( 376*cdf0e10cSrcweir reinterpret_cast< void ** >( &root.m_pUnoI ), 377*cdf0e10cSrcweir xRoot.get(), ::getCppuType( &xRoot ) ); 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir UnoInterfaceReference proxy( 380*cdf0e10cSrcweir // ref count initially 1: 381*cdf0e10cSrcweir new binuno_Proxy( this, proxy_target, oid, pTypeDescr ), 382*cdf0e10cSrcweir SAL_NO_ACQUIRE ); 383*cdf0e10cSrcweir uno_ExtEnvironment * uno_env = 384*cdf0e10cSrcweir m_factory->m_uno_env.get()->pExtEnv; 385*cdf0e10cSrcweir OSL_ASSERT( uno_env != 0 ); 386*cdf0e10cSrcweir (*uno_env->registerProxyInterface)( 387*cdf0e10cSrcweir uno_env, reinterpret_cast< void ** >( &proxy.m_pUnoI ), 388*cdf0e10cSrcweir binuno_proxy_free, oid.pData, 389*cdf0e10cSrcweir reinterpret_cast< typelib_InterfaceTypeDescription * >( 390*cdf0e10cSrcweir pTypeDescr ) ); 391*cdf0e10cSrcweir 392*cdf0e10cSrcweir m_factory->m_uno2cpp.mapInterface( 393*cdf0e10cSrcweir reinterpret_cast< void ** >( &xProxy ), 394*cdf0e10cSrcweir proxy.get(), pTypeDescr ); 395*cdf0e10cSrcweir } 396*cdf0e10cSrcweir } 397*cdf0e10cSrcweir if (xProxy.is()) 398*cdf0e10cSrcweir ret.setValue( &xProxy, pTypeDescr ); 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir catch (...) // finally 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTypeDescr ); 403*cdf0e10cSrcweir throw; 404*cdf0e10cSrcweir } 405*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTypeDescr ); 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir return ret; 408*cdf0e10cSrcweir } 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir //############################################################################## 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir //______________________________________________________________________________ 413*cdf0e10cSrcweir FactoryImpl::FactoryImpl() 414*cdf0e10cSrcweir { 415*cdf0e10cSrcweir OUString uno = OUSTR(UNO_LB_UNO); 416*cdf0e10cSrcweir OUString cpp = OUSTR(CPPU_CURRENT_LANGUAGE_BINDING_NAME); 417*cdf0e10cSrcweir 418*cdf0e10cSrcweir uno_getEnvironment( 419*cdf0e10cSrcweir reinterpret_cast< uno_Environment ** >( &m_uno_env ), uno.pData, 0 ); 420*cdf0e10cSrcweir OSL_ENSURE( m_uno_env.is(), "### cannot get binary uno env!" ); 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir uno_getEnvironment( 423*cdf0e10cSrcweir reinterpret_cast< uno_Environment ** >( &m_cpp_env ), cpp.pData, 0 ); 424*cdf0e10cSrcweir OSL_ENSURE( m_cpp_env.is(), "### cannot get C++ uno env!" ); 425*cdf0e10cSrcweir 426*cdf0e10cSrcweir uno_getMapping( 427*cdf0e10cSrcweir reinterpret_cast< uno_Mapping ** >( &m_uno2cpp ), 428*cdf0e10cSrcweir m_uno_env.get(), m_cpp_env.get(), 0 ); 429*cdf0e10cSrcweir OSL_ENSURE( m_uno2cpp.is(), "### cannot get bridge uno <-> C++!" ); 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir uno_getMapping( 432*cdf0e10cSrcweir reinterpret_cast< uno_Mapping ** >( &m_cpp2uno ), 433*cdf0e10cSrcweir m_cpp_env.get(), m_uno_env.get(), 0 ); 434*cdf0e10cSrcweir OSL_ENSURE( m_cpp2uno.is(), "### cannot get bridge C++ <-> uno!" ); 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); 437*cdf0e10cSrcweir } 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir //______________________________________________________________________________ 440*cdf0e10cSrcweir FactoryImpl::~FactoryImpl() 441*cdf0e10cSrcweir { 442*cdf0e10cSrcweir g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); 443*cdf0e10cSrcweir } 444*cdf0e10cSrcweir 445*cdf0e10cSrcweir // XProxyFactory 446*cdf0e10cSrcweir //______________________________________________________________________________ 447*cdf0e10cSrcweir Reference< XAggregation > FactoryImpl::createProxy( 448*cdf0e10cSrcweir Reference< XInterface > const & xTarget ) 449*cdf0e10cSrcweir throw (RuntimeException) 450*cdf0e10cSrcweir { 451*cdf0e10cSrcweir return new ProxyRoot( this, xTarget ); 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir // XServiceInfo 455*cdf0e10cSrcweir //______________________________________________________________________________ 456*cdf0e10cSrcweir OUString FactoryImpl::getImplementationName() 457*cdf0e10cSrcweir throw (RuntimeException) 458*cdf0e10cSrcweir { 459*cdf0e10cSrcweir return proxyfac_getImplementationName();; 460*cdf0e10cSrcweir } 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir //______________________________________________________________________________ 463*cdf0e10cSrcweir sal_Bool FactoryImpl::supportsService( const OUString & rServiceName ) 464*cdf0e10cSrcweir throw (RuntimeException) 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir Sequence< OUString > const & rSNL = getSupportedServiceNames(); 467*cdf0e10cSrcweir OUString const * pArray = rSNL.getConstArray(); 468*cdf0e10cSrcweir for ( sal_Int32 nPos = rSNL.getLength(); nPos--; ) 469*cdf0e10cSrcweir { 470*cdf0e10cSrcweir if (rServiceName.equals( pArray[ nPos ] )) 471*cdf0e10cSrcweir return true; 472*cdf0e10cSrcweir } 473*cdf0e10cSrcweir return false; 474*cdf0e10cSrcweir } 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir //______________________________________________________________________________ 477*cdf0e10cSrcweir Sequence< OUString > FactoryImpl::getSupportedServiceNames() 478*cdf0e10cSrcweir throw(::com::sun::star::uno::RuntimeException) 479*cdf0e10cSrcweir { 480*cdf0e10cSrcweir return proxyfac_getSupportedServiceNames(); 481*cdf0e10cSrcweir } 482*cdf0e10cSrcweir 483*cdf0e10cSrcweir //============================================================================== 484*cdf0e10cSrcweir static Reference< XInterface > SAL_CALL proxyfac_create( 485*cdf0e10cSrcweir Reference< XComponentContext > const & ) 486*cdf0e10cSrcweir throw (Exception) 487*cdf0e10cSrcweir { 488*cdf0e10cSrcweir Reference< XInterface > xRet; 489*cdf0e10cSrcweir { 490*cdf0e10cSrcweir ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() ); 491*cdf0e10cSrcweir static WeakReference < XInterface > rwInstance; 492*cdf0e10cSrcweir xRet = rwInstance; 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir if (! xRet.is()) 495*cdf0e10cSrcweir { 496*cdf0e10cSrcweir xRet = static_cast< ::cppu::OWeakObject * >(new FactoryImpl); 497*cdf0e10cSrcweir rwInstance = xRet; 498*cdf0e10cSrcweir } 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir return xRet; 501*cdf0e10cSrcweir } 502*cdf0e10cSrcweir 503*cdf0e10cSrcweir static ::cppu::ImplementationEntry g_entries [] = 504*cdf0e10cSrcweir { 505*cdf0e10cSrcweir { 506*cdf0e10cSrcweir proxyfac_create, proxyfac_getImplementationName, 507*cdf0e10cSrcweir proxyfac_getSupportedServiceNames, ::cppu::createSingleComponentFactory, 508*cdf0e10cSrcweir &g_moduleCount.modCnt, 0 509*cdf0e10cSrcweir }, 510*cdf0e10cSrcweir { 0, 0, 0, 0, 0, 0 } 511*cdf0e10cSrcweir }; 512*cdf0e10cSrcweir 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir 515*cdf0e10cSrcweir extern "C" 516*cdf0e10cSrcweir { 517*cdf0e10cSrcweir 518*cdf0e10cSrcweir sal_Bool SAL_CALL component_canUnload( TimeValue * pTime ) 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir return g_moduleCount.canUnload( &g_moduleCount, pTime ); 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir void SAL_CALL component_getImplementationEnvironment( 524*cdf0e10cSrcweir const sal_Char ** ppEnvTypeName, uno_Environment ** ) 525*cdf0e10cSrcweir { 526*cdf0e10cSrcweir *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 527*cdf0e10cSrcweir } 528*cdf0e10cSrcweir 529*cdf0e10cSrcweir void * SAL_CALL component_getFactory( 530*cdf0e10cSrcweir const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey ) 531*cdf0e10cSrcweir { 532*cdf0e10cSrcweir return ::cppu::component_getFactoryHelper( 533*cdf0e10cSrcweir pImplName, pServiceManager, pRegistryKey, g_entries ); 534*cdf0e10cSrcweir } 535*cdf0e10cSrcweir 536*cdf0e10cSrcweir } 537*cdf0e10cSrcweir 538