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