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_cli_ure.hxx" 30*cdf0e10cSrcweir #include "typelib/typedescription.h" 31*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 32*cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp" 33*cdf0e10cSrcweir #include "osl/mutex.hxx" 34*cdf0e10cSrcweir #include "cli_proxy.h" 35*cdf0e10cSrcweir #include "cli_base.h" 36*cdf0e10cSrcweir #include "cli_bridge.h" 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #using <mscorlib.dll> 39*cdf0e10cSrcweir #using <cli_ure.dll> 40*cdf0e10cSrcweir #using <cli_uretypes.dll> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir namespace sr = System::Reflection; 43*cdf0e10cSrcweir namespace st = System::Text; 44*cdf0e10cSrcweir namespace sre = System::Reflection::Emit; 45*cdf0e10cSrcweir namespace sc = System::Collections; 46*cdf0e10cSrcweir namespace srrm = System::Runtime::Remoting::Messaging; 47*cdf0e10cSrcweir namespace srr = System::Runtime::Remoting; 48*cdf0e10cSrcweir namespace srrp = System::Runtime::Remoting::Proxies; 49*cdf0e10cSrcweir namespace sri = System::Runtime::InteropServices; 50*cdf0e10cSrcweir namespace sd = System::Diagnostics; 51*cdf0e10cSrcweir namespace css = com::sun::star; 52*cdf0e10cSrcweir namespace ucss = unoidl::com::sun::star; 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir using namespace cli_uno; 55*cdf0e10cSrcweir using namespace rtl; 56*cdf0e10cSrcweir extern "C" 57*cdf0e10cSrcweir { 58*cdf0e10cSrcweir //------------------------------------------------------------------------------ 59*cdf0e10cSrcweir void SAL_CALL cli_proxy_free( uno_ExtEnvironment * env, void * proxy ) 60*cdf0e10cSrcweir SAL_THROW_EXTERN_C(); 61*cdf0e10cSrcweir //------------------------------------------------------------------------------ 62*cdf0e10cSrcweir void SAL_CALL cli_proxy_acquire( uno_Interface * pUnoI ) 63*cdf0e10cSrcweir SAL_THROW_EXTERN_C(); 64*cdf0e10cSrcweir //------------------------------------------------------------------------------ 65*cdf0e10cSrcweir void SAL_CALL cli_proxy_release( uno_Interface * pUnoI ) 66*cdf0e10cSrcweir SAL_THROW_EXTERN_C(); 67*cdf0e10cSrcweir //------------------------------------------------------------------------------ 68*cdf0e10cSrcweir void SAL_CALL cli_proxy_dispatch( 69*cdf0e10cSrcweir uno_Interface * pUnoI, typelib_TypeDescription const * member_td, 70*cdf0e10cSrcweir void * uno_ret, void * uno_args[], uno_Any ** uno_exc ) 71*cdf0e10cSrcweir SAL_THROW_EXTERN_C(); 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir } 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir namespace cli_uno 77*cdf0e10cSrcweir { 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir UnoInterfaceInfo::UnoInterfaceInfo(Bridge const * bridge, uno_Interface* unoI, 80*cdf0e10cSrcweir typelib_InterfaceTypeDescription* td): 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir m_unoI(unoI), 83*cdf0e10cSrcweir m_typeDesc(td), 84*cdf0e10cSrcweir m_bridge(bridge) 85*cdf0e10cSrcweir { 86*cdf0e10cSrcweir m_bridge->acquire(); 87*cdf0e10cSrcweir m_type = mapUnoType(reinterpret_cast<typelib_TypeDescription*>(td)); 88*cdf0e10cSrcweir m_unoI->acquire(m_unoI); 89*cdf0e10cSrcweir typelib_typedescription_acquire(&m_typeDesc->aBase); 90*cdf0e10cSrcweir if ( ! m_typeDesc->aBase.bComplete) 91*cdf0e10cSrcweir { 92*cdf0e10cSrcweir typelib_TypeDescription* _pt = &m_typeDesc->aBase; 93*cdf0e10cSrcweir sal_Bool bComplete = ::typelib_typedescription_complete( & _pt); 94*cdf0e10cSrcweir if( ! bComplete) 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir OUStringBuffer buf( 128 ); 97*cdf0e10cSrcweir buf.appendAscii(RTL_CONSTASCII_STRINGPARAM( 98*cdf0e10cSrcweir "cannot make type complete: ") ); 99*cdf0e10cSrcweir buf.append( *reinterpret_cast< OUString const * >( 100*cdf0e10cSrcweir & m_typeDesc->aBase.pTypeName)); 101*cdf0e10cSrcweir throw BridgeRuntimeError(buf.makeStringAndClear()); 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir } 104*cdf0e10cSrcweir } 105*cdf0e10cSrcweir UnoInterfaceInfo::~UnoInterfaceInfo() 106*cdf0e10cSrcweir { 107*cdf0e10cSrcweir //accessing unmanaged objects is ok. 108*cdf0e10cSrcweir m_bridge->m_uno_env->revokeInterface( 109*cdf0e10cSrcweir m_bridge->m_uno_env, m_unoI ); 110*cdf0e10cSrcweir m_bridge->release(); 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir m_unoI->release(m_unoI); 113*cdf0e10cSrcweir typelib_typedescription_release( 114*cdf0e10cSrcweir reinterpret_cast<typelib_TypeDescription*>(m_typeDesc)); 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir UnoInterfaceProxy::UnoInterfaceProxy( 118*cdf0e10cSrcweir Bridge * bridge, 119*cdf0e10cSrcweir uno_Interface * pUnoI, 120*cdf0e10cSrcweir typelib_InterfaceTypeDescription* pTD, 121*cdf0e10cSrcweir const OUString& oid ) 122*cdf0e10cSrcweir :RealProxy(__typeof(MarshalByRefObject)), 123*cdf0e10cSrcweir m_bridge(bridge), 124*cdf0e10cSrcweir m_oid(mapUnoString(oid.pData)), 125*cdf0e10cSrcweir m_sTypeName(m_system_Object_String) 126*cdf0e10cSrcweir { 127*cdf0e10cSrcweir m_bridge->acquire(); 128*cdf0e10cSrcweir // create the list that holds all UnoInterfaceInfos 129*cdf0e10cSrcweir m_listIfaces = new ArrayList(10); 130*cdf0e10cSrcweir m_numUnoIfaces = 0; 131*cdf0e10cSrcweir m_listAdditionalProxies = new ArrayList(); 132*cdf0e10cSrcweir m_nlistAdditionalProxies = 0; 133*cdf0e10cSrcweir //put the information of the first UNO interface into the arraylist 134*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 135*cdf0e10cSrcweir _numInterfaces = 0; 136*cdf0e10cSrcweir _sInterfaces = NULL; 137*cdf0e10cSrcweir #endif 138*cdf0e10cSrcweir addUnoInterface(pUnoI, pTD); 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir UnoInterfaceProxy::~UnoInterfaceProxy() 143*cdf0e10cSrcweir { 144*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 145*cdf0e10cSrcweir sd::Trace::WriteLine(System::String::Format( 146*cdf0e10cSrcweir new System::String(S"cli uno bridge: Destroying proxy " 147*cdf0e10cSrcweir S"for UNO object, OID: \n\t{0} \n\twith uno interfaces: "), 148*cdf0e10cSrcweir m_oid)); 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir sd::Trace::WriteLine( mapUnoString(_sInterfaces)); 151*cdf0e10cSrcweir rtl_uString_release(_sInterfaces); 152*cdf0e10cSrcweir #endif 153*cdf0e10cSrcweir //m_bridge is unmanaged, therefore we can access it in this finalizer 154*cdf0e10cSrcweir CliEnvHolder::g_cli_env->revokeInterface(m_oid); 155*cdf0e10cSrcweir m_bridge->release(); 156*cdf0e10cSrcweir } 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir 159*cdf0e10cSrcweir System::Object* UnoInterfaceProxy::create( 160*cdf0e10cSrcweir Bridge * bridge, 161*cdf0e10cSrcweir uno_Interface * pUnoI, 162*cdf0e10cSrcweir typelib_InterfaceTypeDescription* pTD, 163*cdf0e10cSrcweir const OUString& oid) 164*cdf0e10cSrcweir { 165*cdf0e10cSrcweir UnoInterfaceProxy* proxyHandler= 166*cdf0e10cSrcweir new UnoInterfaceProxy(bridge, pUnoI, pTD, oid); 167*cdf0e10cSrcweir System::Object* proxy= proxyHandler->GetTransparentProxy(); 168*cdf0e10cSrcweir CliEnvHolder::g_cli_env->registerInterface(proxy, mapUnoString(oid.pData)); 169*cdf0e10cSrcweir return proxy; 170*cdf0e10cSrcweir } 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir void UnoInterfaceProxy::addUnoInterface(uno_Interface* pUnoI, 174*cdf0e10cSrcweir typelib_InterfaceTypeDescription* pTd) 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir sc::IEnumerator* enumInfos = m_listIfaces->GetEnumerator(); 177*cdf0e10cSrcweir System::Threading::Monitor::Enter(this); 178*cdf0e10cSrcweir try 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir while (enumInfos->MoveNext()) 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir UnoInterfaceInfo* info = static_cast<UnoInterfaceInfo*>( 183*cdf0e10cSrcweir enumInfos->Current); 184*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 185*cdf0e10cSrcweir System::Type * t1; 186*cdf0e10cSrcweir System::Type * t2; 187*cdf0e10cSrcweir t1 = mapUnoType( 188*cdf0e10cSrcweir reinterpret_cast<typelib_TypeDescription*>(info->m_typeDesc) ); 189*cdf0e10cSrcweir t2 = mapUnoType( 190*cdf0e10cSrcweir reinterpret_cast<typelib_TypeDescription*>(pTd) ); 191*cdf0e10cSrcweir #endif 192*cdf0e10cSrcweir if (typelib_typedescription_equals( 193*cdf0e10cSrcweir reinterpret_cast<typelib_TypeDescription*>(info->m_typeDesc), 194*cdf0e10cSrcweir reinterpret_cast<typelib_TypeDescription*>(pTd))) 195*cdf0e10cSrcweir { 196*cdf0e10cSrcweir return; 197*cdf0e10cSrcweir } 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir OUString oid(mapCliString(m_oid)); 200*cdf0e10cSrcweir (*m_bridge->m_uno_env->registerInterface)( 201*cdf0e10cSrcweir m_bridge->m_uno_env, reinterpret_cast< void ** >( &pUnoI ), 202*cdf0e10cSrcweir oid.pData, pTd); 203*cdf0e10cSrcweir //This proxy does not contain the uno_Interface. Add it. 204*cdf0e10cSrcweir m_listIfaces->Add(new UnoInterfaceInfo(m_bridge, pUnoI, pTd)); 205*cdf0e10cSrcweir m_numUnoIfaces = m_listIfaces->Count; 206*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 207*cdf0e10cSrcweir System::String * sInterfaceName = static_cast<UnoInterfaceInfo*>( 208*cdf0e10cSrcweir m_listIfaces->get_Item(m_numUnoIfaces - 1))->m_type->FullName; 209*cdf0e10cSrcweir sd::Trace::WriteLine(System::String::Format( 210*cdf0e10cSrcweir new System::String(S"cli uno bridge: Creating proxy for uno object, " 211*cdf0e10cSrcweir S"id:\n\t{0}\n\t{1}"), m_oid, sInterfaceName)); 212*cdf0e10cSrcweir // add to the string that contains all interface names 213*cdf0e10cSrcweir _numInterfaces ++; 214*cdf0e10cSrcweir OUStringBuffer buf(512); 215*cdf0e10cSrcweir buf.appendAscii("\t"); 216*cdf0e10cSrcweir buf.append( OUString::valueOf((sal_Int32)_numInterfaces)); 217*cdf0e10cSrcweir buf.appendAscii(". "); 218*cdf0e10cSrcweir buf.append(mapCliString(sInterfaceName)); 219*cdf0e10cSrcweir buf.appendAscii("\n"); 220*cdf0e10cSrcweir OUString _sNewInterface = buf.makeStringAndClear(); 221*cdf0e10cSrcweir rtl_uString * __pin * pp_sInterfaces = & _sInterfaces; 222*cdf0e10cSrcweir rtl_uString_newConcat( pp_sInterfaces, * pp_sInterfaces, 223*cdf0e10cSrcweir _sNewInterface.pData); 224*cdf0e10cSrcweir #endif 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir __finally { 227*cdf0e10cSrcweir System::Threading::Monitor::Exit(this); 228*cdf0e10cSrcweir } 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir // IRemotingTypeInfo 233*cdf0e10cSrcweir bool UnoInterfaceProxy::CanCastTo(System::Type* fromType, 234*cdf0e10cSrcweir System::Object*) 235*cdf0e10cSrcweir { 236*cdf0e10cSrcweir if (fromType == __typeof(System::Object)) // trivial case 237*cdf0e10cSrcweir return true; 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir System::Threading::Monitor::Enter(this); 240*cdf0e10cSrcweir try 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir if (0 != findInfo( fromType )) // proxy supports demanded interface 243*cdf0e10cSrcweir return true; 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir //query an uno interface for the required type 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir // we use the first interface in the list (m_listIfaces) to make 248*cdf0e10cSrcweir // the queryInterface call 249*cdf0e10cSrcweir UnoInterfaceInfo* info = 250*cdf0e10cSrcweir static_cast<UnoInterfaceInfo*>(m_listIfaces->get_Item(0)); 251*cdf0e10cSrcweir css::uno::TypeDescription membertd( 252*cdf0e10cSrcweir reinterpret_cast<typelib_InterfaceTypeDescription*>( 253*cdf0e10cSrcweir info->m_typeDesc)->ppAllMembers[0]); 254*cdf0e10cSrcweir System::Object *args[] = new System::Object*[1]; 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir args[0] = fromType; 257*cdf0e10cSrcweir __box uno::Any * pAny; 258*cdf0e10cSrcweir System::Object* pException = NULL; 259*cdf0e10cSrcweir 260*cdf0e10cSrcweir pAny= static_cast<__box uno::Any *>( 261*cdf0e10cSrcweir m_bridge->call_uno( 262*cdf0e10cSrcweir info->m_unoI, 263*cdf0e10cSrcweir membertd.get(), 264*cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription*) 265*cdf0e10cSrcweir membertd.get())->pReturnTypeRef, 266*cdf0e10cSrcweir 1, 267*cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription*) 268*cdf0e10cSrcweir membertd.get())->pParams, 269*cdf0e10cSrcweir args, NULL, &pException) ); 270*cdf0e10cSrcweir 271*cdf0e10cSrcweir // handle regular exception from target 272*cdf0e10cSrcweir OSL_ENSURE( 273*cdf0e10cSrcweir 0 == pException, 274*cdf0e10cSrcweir OUStringToOString( 275*cdf0e10cSrcweir mapCliString( pException->ToString()), 276*cdf0e10cSrcweir RTL_TEXTENCODING_UTF8 ).getStr() ); 277*cdf0e10cSrcweir 278*cdf0e10cSrcweir if (pAny->Type != __typeof (void)) // has value? 279*cdf0e10cSrcweir { 280*cdf0e10cSrcweir if (0 != findInfo( fromType )) 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir // proxy now supports demanded interface 283*cdf0e10cSrcweir return true; 284*cdf0e10cSrcweir } 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir // via aggregation: it is possible that queryInterface() returns 287*cdf0e10cSrcweir // and interface with a different oid. 288*cdf0e10cSrcweir // That way, this type is supported for the CLI 289*cdf0e10cSrcweir // interpreter (CanCastTo() returns true) 290*cdf0e10cSrcweir ::System::Object * obj = pAny->Value; 291*cdf0e10cSrcweir OSL_ASSERT( srr::RemotingServices::IsTransparentProxy( obj ) ); 292*cdf0e10cSrcweir if (srr::RemotingServices::IsTransparentProxy( obj )) 293*cdf0e10cSrcweir { 294*cdf0e10cSrcweir UnoInterfaceProxy * proxy = 295*cdf0e10cSrcweir static_cast< UnoInterfaceProxy * >( 296*cdf0e10cSrcweir srr::RemotingServices::GetRealProxy( obj ) ); 297*cdf0e10cSrcweir OSL_ASSERT( 0 != proxy->findInfo( fromType ) ); 298*cdf0e10cSrcweir m_listAdditionalProxies->Add( proxy ); 299*cdf0e10cSrcweir m_nlistAdditionalProxies = m_listAdditionalProxies->Count; 300*cdf0e10cSrcweir OSL_ASSERT( 0 != findInfo( fromType ) ); 301*cdf0e10cSrcweir return true; 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir } 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir catch (BridgeRuntimeError& e) 306*cdf0e10cSrcweir { 307*cdf0e10cSrcweir (void) e; // avoid warning 308*cdf0e10cSrcweir OSL_ENSURE( 309*cdf0e10cSrcweir 0, OUStringToOString( 310*cdf0e10cSrcweir e.m_message, RTL_TEXTENCODING_UTF8 ).getStr() ); 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir catch (System::Exception* e) 313*cdf0e10cSrcweir { 314*cdf0e10cSrcweir System::String* msg= new System::String( 315*cdf0e10cSrcweir S"An unexpected CLI exception occurred in " 316*cdf0e10cSrcweir S"UnoInterfaceProxy::CanCastTo(). Original" 317*cdf0e10cSrcweir S"message: \n"); 318*cdf0e10cSrcweir msg= System::String::Concat(msg, e->get_Message()); 319*cdf0e10cSrcweir OSL_ENSURE( 320*cdf0e10cSrcweir 0, OUStringToOString( 321*cdf0e10cSrcweir mapCliString(msg), RTL_TEXTENCODING_UTF8 ).getStr() ); 322*cdf0e10cSrcweir } 323*cdf0e10cSrcweir catch (...) 324*cdf0e10cSrcweir { 325*cdf0e10cSrcweir OSL_ENSURE( 326*cdf0e10cSrcweir 0, "An unexpected native C++ exception occurred in " 327*cdf0e10cSrcweir "UnoInterfaceProxy::CanCastTo()" ); 328*cdf0e10cSrcweir } 329*cdf0e10cSrcweir __finally 330*cdf0e10cSrcweir { 331*cdf0e10cSrcweir System::Threading::Monitor::Exit(this); 332*cdf0e10cSrcweir } 333*cdf0e10cSrcweir return false; 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir srrm::IMessage* UnoInterfaceProxy::invokeObject( 337*cdf0e10cSrcweir sc::IDictionary* props, 338*cdf0e10cSrcweir srrm::LogicalCallContext* context, 339*cdf0e10cSrcweir srrm::IMethodCallMessage* mcm) 340*cdf0e10cSrcweir { 341*cdf0e10cSrcweir System::Object* retMethod = 0; 342*cdf0e10cSrcweir System::String* sMethod = static_cast<System::String*> 343*cdf0e10cSrcweir (props->get_Item(m_methodNameString)); 344*cdf0e10cSrcweir System::Object* args[] = static_cast<System::Object*[]>( 345*cdf0e10cSrcweir props->get_Item(m_ArgsString)); 346*cdf0e10cSrcweir if (m_Equals_String->Equals(sMethod)) 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir // Object.Equals 349*cdf0e10cSrcweir OSL_ASSERT(args->get_Length() == 1); 350*cdf0e10cSrcweir srrp::RealProxy* rProxy = srr::RemotingServices::GetRealProxy(args[0]); 351*cdf0e10cSrcweir bool bDone = false; 352*cdf0e10cSrcweir if (rProxy) 353*cdf0e10cSrcweir { 354*cdf0e10cSrcweir UnoInterfaceProxy* unoProxy = 355*cdf0e10cSrcweir dynamic_cast<UnoInterfaceProxy*>(rProxy); 356*cdf0e10cSrcweir if (unoProxy) 357*cdf0e10cSrcweir { 358*cdf0e10cSrcweir bool b = m_oid->Equals(unoProxy->getOid()); 359*cdf0e10cSrcweir retMethod = __box(b); 360*cdf0e10cSrcweir bDone = true; 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir } 363*cdf0e10cSrcweir if (bDone == false) 364*cdf0e10cSrcweir { 365*cdf0e10cSrcweir //no proxy or not our proxy, therefore Equals must be false 366*cdf0e10cSrcweir retMethod = __box(false); 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir } 369*cdf0e10cSrcweir else if (m_GetHashCode_String->Equals(sMethod)) 370*cdf0e10cSrcweir { 371*cdf0e10cSrcweir // Object.GetHashCode 372*cdf0e10cSrcweir int nHash = m_oid->GetHashCode(); 373*cdf0e10cSrcweir retMethod = __box(nHash); 374*cdf0e10cSrcweir } 375*cdf0e10cSrcweir else if (m_GetType_String->Equals(sMethod)) 376*cdf0e10cSrcweir { 377*cdf0e10cSrcweir // Object.GetType 378*cdf0e10cSrcweir retMethod = __typeof(System::Object); 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir else if (m_ToString_String->Equals(sMethod)) 381*cdf0e10cSrcweir { 382*cdf0e10cSrcweir // Object.ToString 383*cdf0e10cSrcweir st::StringBuilder* sb = new st::StringBuilder(256); 384*cdf0e10cSrcweir // sb->AppendFormat(S"Uno object proxy. Implemented interface: {0}" 385*cdf0e10cSrcweir // S". OID: {1}", m_type->ToString(), m_oid); 386*cdf0e10cSrcweir sb->AppendFormat(S"Uno object proxy. OID: {0}", m_oid); 387*cdf0e10cSrcweir retMethod = sb->ToString(); 388*cdf0e10cSrcweir } 389*cdf0e10cSrcweir else 390*cdf0e10cSrcweir { 391*cdf0e10cSrcweir //Either Object has new functions or a protected method was called 392*cdf0e10cSrcweir //which should not be possible 393*cdf0e10cSrcweir OSL_ASSERT(0); 394*cdf0e10cSrcweir } 395*cdf0e10cSrcweir srrm::IMessage* retVal= new srrm::ReturnMessage( 396*cdf0e10cSrcweir retMethod, new System::Object*[0], 0, context, mcm); 397*cdf0e10cSrcweir return retVal; 398*cdf0e10cSrcweir } 399*cdf0e10cSrcweir 400*cdf0e10cSrcweir UnoInterfaceInfo * UnoInterfaceProxy::findInfo( ::System::Type * type ) 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir for (int i = 0; i < m_numUnoIfaces; i++) 403*cdf0e10cSrcweir { 404*cdf0e10cSrcweir UnoInterfaceInfo* tmpInfo = static_cast<UnoInterfaceInfo*>( 405*cdf0e10cSrcweir m_listIfaces->get_Item(i)); 406*cdf0e10cSrcweir if (type->IsAssignableFrom(tmpInfo->m_type)) 407*cdf0e10cSrcweir return tmpInfo; 408*cdf0e10cSrcweir } 409*cdf0e10cSrcweir for ( int i = 0; i < m_nlistAdditionalProxies; ++i ) 410*cdf0e10cSrcweir { 411*cdf0e10cSrcweir UnoInterfaceProxy * proxy = 412*cdf0e10cSrcweir static_cast< UnoInterfaceProxy * >( 413*cdf0e10cSrcweir m_listAdditionalProxies->get_Item( i ) ); 414*cdf0e10cSrcweir UnoInterfaceInfo * info = proxy->findInfo( type ); 415*cdf0e10cSrcweir if (0 != info) 416*cdf0e10cSrcweir return info; 417*cdf0e10cSrcweir } 418*cdf0e10cSrcweir return 0; 419*cdf0e10cSrcweir } 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir srrm::IMessage* UnoInterfaceProxy::Invoke(srrm::IMessage* callmsg) 422*cdf0e10cSrcweir { 423*cdf0e10cSrcweir try 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir sc::IDictionary* props= callmsg->Properties; 426*cdf0e10cSrcweir srrm::LogicalCallContext* context= 427*cdf0e10cSrcweir static_cast<srrm::LogicalCallContext*>( 428*cdf0e10cSrcweir props->get_Item(m_CallContextString)); 429*cdf0e10cSrcweir srrm::IMethodCallMessage* mcm= 430*cdf0e10cSrcweir static_cast<srrm::IMethodCallMessage*>(callmsg); 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir //Find out which UNO interface is being called 433*cdf0e10cSrcweir System::String* sTypeName = static_cast<System::String*>( 434*cdf0e10cSrcweir props->get_Item(m_typeNameString)); 435*cdf0e10cSrcweir sTypeName = sTypeName->Substring(0, sTypeName->IndexOf(',')); 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir // Special Handling for System.Object methods 438*cdf0e10cSrcweir if(sTypeName->IndexOf(m_system_Object_String) != -1) 439*cdf0e10cSrcweir { 440*cdf0e10cSrcweir return invokeObject(props, context, mcm); 441*cdf0e10cSrcweir } 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir System::Type* typeBeingCalled = loadCliType(sTypeName); 444*cdf0e10cSrcweir UnoInterfaceInfo* info = findInfo( typeBeingCalled ); 445*cdf0e10cSrcweir OSL_ASSERT( 0 != info ); 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir // ToDo do without string conversion, a OUString is not needed here 448*cdf0e10cSrcweir // get the type description of the call 449*cdf0e10cSrcweir OUString usMethodName(mapCliString(static_cast<System::String*>( 450*cdf0e10cSrcweir props->get_Item(m_methodNameString)))); 451*cdf0e10cSrcweir typelib_TypeDescriptionReference ** ppAllMembers = 452*cdf0e10cSrcweir info->m_typeDesc->ppAllMembers; 453*cdf0e10cSrcweir sal_Int32 numberMembers = info->m_typeDesc->nAllMembers; 454*cdf0e10cSrcweir for ( sal_Int32 nPos = numberMembers; nPos--; ) 455*cdf0e10cSrcweir { 456*cdf0e10cSrcweir typelib_TypeDescriptionReference * member_type = ppAllMembers[nPos]; 457*cdf0e10cSrcweir 458*cdf0e10cSrcweir // check usMethodName against fully qualified usTypeName 459*cdf0e10cSrcweir // of member_type; usTypeName is of the form 460*cdf0e10cSrcweir // <name> "::" <usMethodName> *(":@" <idx> "," <idx> ":" <name>) 461*cdf0e10cSrcweir OUString const & usTypeName = 462*cdf0e10cSrcweir OUString::unacquired( & member_type->pTypeName ); 463*cdf0e10cSrcweir 464*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 465*cdf0e10cSrcweir System::String * pTypeName; 466*cdf0e10cSrcweir pTypeName = mapUnoString(usTypeName.pData); 467*cdf0e10cSrcweir #endif 468*cdf0e10cSrcweir sal_Int32 offset = usTypeName.indexOf( ':' ) + 2; 469*cdf0e10cSrcweir OSL_ASSERT( 470*cdf0e10cSrcweir offset >= 2 && offset < usTypeName.getLength() 471*cdf0e10cSrcweir && usTypeName[offset - 1] == ':' ); 472*cdf0e10cSrcweir sal_Int32 remainder = usTypeName.getLength() - offset; 473*cdf0e10cSrcweir 474*cdf0e10cSrcweir if (typelib_TypeClass_INTERFACE_METHOD == member_type->eTypeClass) 475*cdf0e10cSrcweir { 476*cdf0e10cSrcweir if ((usMethodName.getLength() == remainder 477*cdf0e10cSrcweir || (usMethodName.getLength() < remainder 478*cdf0e10cSrcweir && usTypeName[offset + usMethodName.getLength()] == ':')) 479*cdf0e10cSrcweir && usTypeName.match(usMethodName, offset)) 480*cdf0e10cSrcweir { 481*cdf0e10cSrcweir TypeDescr member_td( member_type ); 482*cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription * method_td = 483*cdf0e10cSrcweir (typelib_InterfaceMethodTypeDescription *) 484*cdf0e10cSrcweir member_td.get(); 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir System::Object* args[] = static_cast<System::Object*[]>( 487*cdf0e10cSrcweir props->get_Item(m_ArgsString)); 488*cdf0e10cSrcweir System::Type* argTypes[] = static_cast<System::Type*[]>( 489*cdf0e10cSrcweir props->get_Item(m_methodSignatureString)); 490*cdf0e10cSrcweir System::Object* pExc = NULL; 491*cdf0e10cSrcweir System::Object * cli_ret = m_bridge->call_uno( 492*cdf0e10cSrcweir info->m_unoI, member_td.get(), 493*cdf0e10cSrcweir method_td->pReturnTypeRef, method_td->nParams, 494*cdf0e10cSrcweir method_td->pParams, args, argTypes, &pExc); 495*cdf0e10cSrcweir return constructReturnMessage(cli_ret, args, method_td, 496*cdf0e10cSrcweir callmsg, pExc); 497*cdf0e10cSrcweir break; 498*cdf0e10cSrcweir } 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir else 501*cdf0e10cSrcweir { 502*cdf0e10cSrcweir OSL_ASSERT( typelib_TypeClass_INTERFACE_ATTRIBUTE == 503*cdf0e10cSrcweir member_type->eTypeClass ); 504*cdf0e10cSrcweir if (usMethodName.getLength() > 4 505*cdf0e10cSrcweir && (usMethodName.getLength() - 4 == remainder 506*cdf0e10cSrcweir || (usMethodName.getLength() - 4 < remainder 507*cdf0e10cSrcweir && usTypeName[ 508*cdf0e10cSrcweir offset + (usMethodName.getLength() - 4)] == ':')) 509*cdf0e10cSrcweir && usMethodName[1] == 'e' && usMethodName[2] == 't' 510*cdf0e10cSrcweir && rtl_ustr_compare_WithLength( 511*cdf0e10cSrcweir usTypeName.getStr() + offset, 512*cdf0e10cSrcweir usMethodName.getLength() - 4, 513*cdf0e10cSrcweir usMethodName.getStr() + 4, 514*cdf0e10cSrcweir usMethodName.getLength() - 4) == 0) 515*cdf0e10cSrcweir { 516*cdf0e10cSrcweir if ('g' == usMethodName[0]) 517*cdf0e10cSrcweir { 518*cdf0e10cSrcweir TypeDescr member_td( member_type ); 519*cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription * attribute_td = 520*cdf0e10cSrcweir (typelib_InterfaceAttributeTypeDescription*) 521*cdf0e10cSrcweir member_td.get(); 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir System::Object* pExc = NULL; 524*cdf0e10cSrcweir System::Object* cli_ret= m_bridge->call_uno( 525*cdf0e10cSrcweir info->m_unoI, member_td.get(), 526*cdf0e10cSrcweir attribute_td->pAttributeTypeRef, 527*cdf0e10cSrcweir 0, 0, 528*cdf0e10cSrcweir NULL, NULL, &pExc); 529*cdf0e10cSrcweir return constructReturnMessage(cli_ret, NULL, NULL, 530*cdf0e10cSrcweir callmsg, pExc); 531*cdf0e10cSrcweir } 532*cdf0e10cSrcweir else if ('s' == usMethodName[0]) 533*cdf0e10cSrcweir { 534*cdf0e10cSrcweir TypeDescr member_td( member_type ); 535*cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription * attribute_td = 536*cdf0e10cSrcweir (typelib_InterfaceAttributeTypeDescription *) 537*cdf0e10cSrcweir member_td.get(); 538*cdf0e10cSrcweir if (! attribute_td->bReadOnly) 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir typelib_MethodParameter param; 541*cdf0e10cSrcweir param.pTypeRef = attribute_td->pAttributeTypeRef; 542*cdf0e10cSrcweir param.bIn = sal_True; 543*cdf0e10cSrcweir param.bOut = sal_False; 544*cdf0e10cSrcweir 545*cdf0e10cSrcweir System::Object* args[] = 546*cdf0e10cSrcweir static_cast<System::Object*[]>( 547*cdf0e10cSrcweir props->get_Item(m_ArgsString)); 548*cdf0e10cSrcweir System::Object* pExc = NULL; 549*cdf0e10cSrcweir m_bridge->call_uno( 550*cdf0e10cSrcweir info->m_unoI, member_td.get(), 551*cdf0e10cSrcweir ::getCppuVoidType().getTypeLibType(), 552*cdf0e10cSrcweir 1, ¶m, args, NULL, &pExc); 553*cdf0e10cSrcweir return constructReturnMessage(NULL, NULL, NULL, 554*cdf0e10cSrcweir callmsg, pExc); 555*cdf0e10cSrcweir } 556*cdf0e10cSrcweir else 557*cdf0e10cSrcweir { 558*cdf0e10cSrcweir return constructReturnMessage(NULL, NULL, NULL, 559*cdf0e10cSrcweir callmsg, NULL); 560*cdf0e10cSrcweir } 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir break; 563*cdf0e10cSrcweir } 564*cdf0e10cSrcweir } 565*cdf0e10cSrcweir } 566*cdf0e10cSrcweir // ToDo check if the message of the exception is not crippled 567*cdf0e10cSrcweir // the thing that should not be... no method info found! 568*cdf0e10cSrcweir OUStringBuffer buf( 64 ); 569*cdf0e10cSrcweir buf.appendAscii(RTL_CONSTASCII_STRINGPARAM( 570*cdf0e10cSrcweir "[cli_uno bridge]calling undeclared function on " 571*cdf0e10cSrcweir "interface ") ); 572*cdf0e10cSrcweir buf.append( *reinterpret_cast< OUString const * >( 573*cdf0e10cSrcweir & ((typelib_TypeDescription *)info->m_typeDesc)->pTypeName)); 574*cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") ); 575*cdf0e10cSrcweir buf.append( usMethodName ); 576*cdf0e10cSrcweir throw BridgeRuntimeError( buf.makeStringAndClear() ); 577*cdf0e10cSrcweir } 578*cdf0e10cSrcweir catch (BridgeRuntimeError & err) 579*cdf0e10cSrcweir { 580*cdf0e10cSrcweir srrm::IMethodCallMessage* mcm = 581*cdf0e10cSrcweir static_cast<srrm::IMethodCallMessage*>(callmsg); 582*cdf0e10cSrcweir return new srrm::ReturnMessage(new ucss::uno::RuntimeException( 583*cdf0e10cSrcweir mapUnoString(err.m_message.pData), NULL), mcm); 584*cdf0e10cSrcweir } 585*cdf0e10cSrcweir catch (System::Exception* e) 586*cdf0e10cSrcweir { 587*cdf0e10cSrcweir st::StringBuilder * sb = new st::StringBuilder(512); 588*cdf0e10cSrcweir sb->Append(new System::String( 589*cdf0e10cSrcweir S"An unexpected CLI exception occurred in " 590*cdf0e10cSrcweir S"UnoInterfaceProxy::Invoke. Original" 591*cdf0e10cSrcweir S"message: \n")); 592*cdf0e10cSrcweir sb->Append(e->get_Message()); 593*cdf0e10cSrcweir sb->Append((__wchar_t) '\n'); 594*cdf0e10cSrcweir sb->Append(e->get_StackTrace()); 595*cdf0e10cSrcweir srrm::IMethodCallMessage* mcm = 596*cdf0e10cSrcweir static_cast<srrm::IMethodCallMessage*>(callmsg); 597*cdf0e10cSrcweir return new srrm::ReturnMessage(new ucss::uno::RuntimeException( 598*cdf0e10cSrcweir sb->ToString(), NULL), mcm); 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir catch (...) 601*cdf0e10cSrcweir { 602*cdf0e10cSrcweir System::String* msg = new System::String( 603*cdf0e10cSrcweir S"An unexpected native C++ exception occurred in " 604*cdf0e10cSrcweir S"UnoInterfaceProxy::Invoke."); 605*cdf0e10cSrcweir srrm::IMethodCallMessage* mcm = 606*cdf0e10cSrcweir static_cast<srrm::IMethodCallMessage*>(callmsg); 607*cdf0e10cSrcweir return new srrm::ReturnMessage(new ucss::uno::RuntimeException( 608*cdf0e10cSrcweir msg, NULL), mcm); 609*cdf0e10cSrcweir } 610*cdf0e10cSrcweir return NULL; 611*cdf0e10cSrcweir } 612*cdf0e10cSrcweir /** If the argument args is NULL then this function is called for an attribute 613*cdf0e10cSrcweir method (either setXXX or getXXX). 614*cdf0e10cSrcweir For attributes the argument mtd is also NULL. 615*cdf0e10cSrcweir */ 616*cdf0e10cSrcweir srrm::IMessage* UnoInterfaceProxy::constructReturnMessage( 617*cdf0e10cSrcweir System::Object* cliReturn, 618*cdf0e10cSrcweir System::Object* args[], 619*cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription* mtd, 620*cdf0e10cSrcweir srrm::IMessage* msg, System::Object* exc) 621*cdf0e10cSrcweir { 622*cdf0e10cSrcweir srrm::IMessage * retVal= NULL; 623*cdf0e10cSrcweir srrm::IMethodCallMessage* mcm = static_cast<srrm::IMethodCallMessage*>(msg); 624*cdf0e10cSrcweir if (exc) 625*cdf0e10cSrcweir { 626*cdf0e10cSrcweir retVal = new srrm::ReturnMessage( 627*cdf0e10cSrcweir dynamic_cast<System::Exception*>(exc), mcm); 628*cdf0e10cSrcweir } 629*cdf0e10cSrcweir else 630*cdf0e10cSrcweir { 631*cdf0e10cSrcweir sc::IDictionary* props= msg->get_Properties(); 632*cdf0e10cSrcweir srrm::LogicalCallContext* context= 633*cdf0e10cSrcweir static_cast<srrm::LogicalCallContext*>( 634*cdf0e10cSrcweir props->get_Item(m_CallContextString)); 635*cdf0e10cSrcweir if (args != NULL) 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir // Method 638*cdf0e10cSrcweir //build the array of out parameters, allocate max length 639*cdf0e10cSrcweir System::Object* arOut[]= new System::Object*[mtd->nParams]; 640*cdf0e10cSrcweir int nOut = 0; 641*cdf0e10cSrcweir for (int i= 0; i < mtd->nParams; i++) 642*cdf0e10cSrcweir { 643*cdf0e10cSrcweir if (mtd->pParams[i].bOut) 644*cdf0e10cSrcweir { 645*cdf0e10cSrcweir arOut[i]= args[i]; 646*cdf0e10cSrcweir nOut++; 647*cdf0e10cSrcweir } 648*cdf0e10cSrcweir } 649*cdf0e10cSrcweir retVal= new srrm::ReturnMessage(cliReturn, arOut, nOut, 650*cdf0e10cSrcweir context, mcm); 651*cdf0e10cSrcweir } 652*cdf0e10cSrcweir else 653*cdf0e10cSrcweir { 654*cdf0e10cSrcweir // Attribute (getXXX) 655*cdf0e10cSrcweir retVal= new srrm::ReturnMessage(cliReturn, NULL, 0, 656*cdf0e10cSrcweir context, mcm); 657*cdf0e10cSrcweir } 658*cdf0e10cSrcweir } 659*cdf0e10cSrcweir return retVal; 660*cdf0e10cSrcweir } 661*cdf0e10cSrcweir 662*cdf0e10cSrcweir //################################################################################ 663*cdf0e10cSrcweir CliProxy::CliProxy(Bridge const* bridge, System::Object* cliI, 664*cdf0e10cSrcweir typelib_TypeDescription const* td, 665*cdf0e10cSrcweir const rtl::OUString& usOid): 666*cdf0e10cSrcweir m_ref(1), 667*cdf0e10cSrcweir m_bridge(bridge), 668*cdf0e10cSrcweir m_cliI(cliI), 669*cdf0e10cSrcweir m_unoType(const_cast<typelib_TypeDescription*>(td)), 670*cdf0e10cSrcweir m_usOid(usOid), 671*cdf0e10cSrcweir m_oid(mapUnoString(usOid.pData)), 672*cdf0e10cSrcweir m_nInheritedInterfaces(0) 673*cdf0e10cSrcweir { 674*cdf0e10cSrcweir m_bridge->acquire(); 675*cdf0e10cSrcweir uno_Interface::acquire = cli_proxy_acquire; 676*cdf0e10cSrcweir uno_Interface::release = cli_proxy_release; 677*cdf0e10cSrcweir uno_Interface::pDispatcher = cli_proxy_dispatch; 678*cdf0e10cSrcweir 679*cdf0e10cSrcweir m_unoType.makeComplete(); 680*cdf0e10cSrcweir m_type= mapUnoType(m_unoType.get()); 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir makeMethodInfos(); 683*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 684*cdf0e10cSrcweir sd::Trace::WriteLine(System::String::Format( 685*cdf0e10cSrcweir new System::String(S"cli uno bridge: Creating proxy for cli object, " 686*cdf0e10cSrcweir S"id:\n\t{0}\n\t{1}"), m_oid, m_type)); 687*cdf0e10cSrcweir #endif 688*cdf0e10cSrcweir 689*cdf0e10cSrcweir } 690*cdf0e10cSrcweir 691*cdf0e10cSrcweir void CliProxy::makeMethodInfos() 692*cdf0e10cSrcweir { 693*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 694*cdf0e10cSrcweir System::Object* cliI; 695*cdf0e10cSrcweir System::Type* type; 696*cdf0e10cSrcweir cliI = m_cliI; 697*cdf0e10cSrcweir type = m_type; 698*cdf0e10cSrcweir #endif 699*cdf0e10cSrcweir 700*cdf0e10cSrcweir if (m_type->get_IsInterface() == false) 701*cdf0e10cSrcweir return; 702*cdf0e10cSrcweir sr::MethodInfo* arThisMethods[] = m_type->GetMethods(); 703*cdf0e10cSrcweir //get the inherited interfaces 704*cdf0e10cSrcweir System::Type* arInheritedIfaces[] = m_type->GetInterfaces(); 705*cdf0e10cSrcweir m_nInheritedInterfaces = arInheritedIfaces->get_Length(); 706*cdf0e10cSrcweir //array containing the number of methods for the interface and its 707*cdf0e10cSrcweir //inherited interfaces 708*cdf0e10cSrcweir m_arInterfaceMethodCount = new int __gc [m_nInheritedInterfaces + 1]; 709*cdf0e10cSrcweir //determine the number of all interface methods, including the inherited 710*cdf0e10cSrcweir //interfaces 711*cdf0e10cSrcweir int numMethods = arThisMethods->get_Length(); 712*cdf0e10cSrcweir for (int i= 0; i < m_nInheritedInterfaces; i++) 713*cdf0e10cSrcweir { 714*cdf0e10cSrcweir numMethods += arInheritedIfaces[i]->GetMethods()->get_Length(); 715*cdf0e10cSrcweir } 716*cdf0e10cSrcweir //array containing MethodInfos of the cli object 717*cdf0e10cSrcweir m_arMethodInfos = new sr::MethodInfo*[numMethods]; 718*cdf0e10cSrcweir //array containing MethodInfos of the interface 719*cdf0e10cSrcweir m_arInterfaceMethodInfos = new sr::MethodInfo*[numMethods]; 720*cdf0e10cSrcweir //array containing the mapping of Uno interface pos to pos in 721*cdf0e10cSrcweir //m_arMethodInfos 722*cdf0e10cSrcweir m_arUnoPosToCliPos = new System::Int32[numMethods]; 723*cdf0e10cSrcweir // initialize with -1 724*cdf0e10cSrcweir for (int i = 0; i < numMethods; i++) 725*cdf0e10cSrcweir m_arUnoPosToCliPos[i] = -1; 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 728*cdf0e10cSrcweir sr::MethodInfo* arMethodInfosDbg[]; 729*cdf0e10cSrcweir sr::MethodInfo* arInterfaceMethodInfosDbg[]; 730*cdf0e10cSrcweir System::Int32 arInterfaceMethodCountDbg[]; 731*cdf0e10cSrcweir arMethodInfosDbg = m_arMethodInfos; 732*cdf0e10cSrcweir arInterfaceMethodInfosDbg = m_arInterfaceMethodInfos; 733*cdf0e10cSrcweir arInterfaceMethodCountDbg = m_arInterfaceMethodCount; 734*cdf0e10cSrcweir #endif 735*cdf0e10cSrcweir 736*cdf0e10cSrcweir 737*cdf0e10cSrcweir //fill m_arMethodInfos with the mappings 738*cdf0e10cSrcweir // !!! InterfaceMapping.TargetMethods should be MethodInfo*[] according 739*cdf0e10cSrcweir // to documentation 740*cdf0e10cSrcweir // but it is Type*[] instead. Bug in the framework? 741*cdf0e10cSrcweir System::Type* objType = m_cliI->GetType(); 742*cdf0e10cSrcweir try 743*cdf0e10cSrcweir { 744*cdf0e10cSrcweir int index = 0; 745*cdf0e10cSrcweir // now get the methods from the inherited interface 746*cdf0e10cSrcweir //arInheritedIfaces[0] is the direct base interface 747*cdf0e10cSrcweir //arInheritedIfaces[n] is the furthest inherited interface 748*cdf0e10cSrcweir //Start with the base interface 749*cdf0e10cSrcweir int nArLength = arInheritedIfaces->get_Length(); 750*cdf0e10cSrcweir for (;nArLength > 0; nArLength--) 751*cdf0e10cSrcweir { 752*cdf0e10cSrcweir sr::InterfaceMapping mapInherited = objType->GetInterfaceMap( 753*cdf0e10cSrcweir arInheritedIfaces[nArLength - 1]); 754*cdf0e10cSrcweir int numMethods = mapInherited.TargetMethods->get_Length(); 755*cdf0e10cSrcweir m_arInterfaceMethodCount[nArLength - 1] = numMethods; 756*cdf0e10cSrcweir for (int i = 0; i < numMethods; i++, index++) 757*cdf0e10cSrcweir { 758*cdf0e10cSrcweir m_arMethodInfos[index] = __try_cast<sr::MethodInfo*>( 759*cdf0e10cSrcweir mapInherited.TargetMethods[i]); 760*cdf0e10cSrcweir 761*cdf0e10cSrcweir m_arInterfaceMethodInfos[index] = __try_cast<sr::MethodInfo*>( 762*cdf0e10cSrcweir mapInherited.InterfaceMethods[i]); 763*cdf0e10cSrcweir } 764*cdf0e10cSrcweir } 765*cdf0e10cSrcweir //At last come the methods of the furthest derived interface 766*cdf0e10cSrcweir sr::InterfaceMapping map = objType->GetInterfaceMap(m_type); 767*cdf0e10cSrcweir nArLength = map.TargetMethods->get_Length(); 768*cdf0e10cSrcweir m_arInterfaceMethodCount[m_nInheritedInterfaces] = nArLength; 769*cdf0e10cSrcweir for (int i = 0; i < nArLength; i++,index++) 770*cdf0e10cSrcweir { 771*cdf0e10cSrcweir m_arMethodInfos[index]= __try_cast<sr::MethodInfo*>( 772*cdf0e10cSrcweir map.TargetMethods[i]); 773*cdf0e10cSrcweir m_arInterfaceMethodInfos[index]= __try_cast<sr::MethodInfo*>( 774*cdf0e10cSrcweir map.InterfaceMethods[i]); 775*cdf0e10cSrcweir } 776*cdf0e10cSrcweir } 777*cdf0e10cSrcweir catch (System::InvalidCastException* ) 778*cdf0e10cSrcweir { 779*cdf0e10cSrcweir OUStringBuffer buf( 128 ); 780*cdf0e10cSrcweir buf.appendAscii(RTL_CONSTASCII_STRINGPARAM( 781*cdf0e10cSrcweir "[cli_uno bridge] preparing proxy for " 782*cdf0e10cSrcweir "cli interface: ") ); 783*cdf0e10cSrcweir buf.append(mapCliString(m_type->ToString() )); 784*cdf0e10cSrcweir buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(" \nfailed!")); 785*cdf0e10cSrcweir throw BridgeRuntimeError( buf.makeStringAndClear() ); 786*cdf0e10cSrcweir } 787*cdf0e10cSrcweir } 788*cdf0e10cSrcweir 789*cdf0e10cSrcweir sr::MethodInfo* CliProxy::getMethodInfo(int nUnoFunctionPos, 790*cdf0e10cSrcweir const rtl::OUString& usMethodName, MethodKind methodKind) 791*cdf0e10cSrcweir { 792*cdf0e10cSrcweir sr::MethodInfo* ret = NULL; 793*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 794*cdf0e10cSrcweir System::String* sMethodNameDbg; 795*cdf0e10cSrcweir sr::MethodInfo* arMethodInfosDbg[]; 796*cdf0e10cSrcweir sr::MethodInfo* arInterfaceMethodInfosDbg[]; 797*cdf0e10cSrcweir System::Int32 arInterfaceMethodCountDbg[]; 798*cdf0e10cSrcweir System::Int32 arUnoPosToCliPosDbg[]; 799*cdf0e10cSrcweir sMethodNameDbg = mapUnoString(usMethodName.pData); 800*cdf0e10cSrcweir arMethodInfosDbg = m_arMethodInfos; 801*cdf0e10cSrcweir arInterfaceMethodInfosDbg = m_arInterfaceMethodInfos; 802*cdf0e10cSrcweir arInterfaceMethodCountDbg = m_arInterfaceMethodCount; 803*cdf0e10cSrcweir arUnoPosToCliPosDbg = m_arUnoPosToCliPos; 804*cdf0e10cSrcweir #endif 805*cdf0e10cSrcweir //deduct 3 for XInterface methods 806*cdf0e10cSrcweir nUnoFunctionPos -= 3; 807*cdf0e10cSrcweir System::Threading::Monitor::Enter(m_arUnoPosToCliPos); 808*cdf0e10cSrcweir try 809*cdf0e10cSrcweir { 810*cdf0e10cSrcweir int cliPos = m_arUnoPosToCliPos[nUnoFunctionPos]; 811*cdf0e10cSrcweir if (cliPos != -1) 812*cdf0e10cSrcweir return m_arMethodInfos[cliPos]; 813*cdf0e10cSrcweir 814*cdf0e10cSrcweir //create the method function name 815*cdf0e10cSrcweir System::String* sMethodName = mapUnoString(usMethodName.pData); 816*cdf0e10cSrcweir switch (methodKind) 817*cdf0e10cSrcweir { 818*cdf0e10cSrcweir case MK_METHOD: 819*cdf0e10cSrcweir break; 820*cdf0e10cSrcweir case MK_SET: 821*cdf0e10cSrcweir sMethodName = System::String::Concat( 822*cdf0e10cSrcweir const_cast<System::String*>(Constants::sAttributeSet), 823*cdf0e10cSrcweir sMethodName); 824*cdf0e10cSrcweir break; 825*cdf0e10cSrcweir case MK_GET: 826*cdf0e10cSrcweir sMethodName = System::String::Concat( 827*cdf0e10cSrcweir const_cast<System::String*>(Constants::sAttributeGet), 828*cdf0e10cSrcweir sMethodName); 829*cdf0e10cSrcweir break; 830*cdf0e10cSrcweir default: 831*cdf0e10cSrcweir OSL_ASSERT(0); 832*cdf0e10cSrcweir } 833*cdf0e10cSrcweir //Find the cli interface method that corresponds to the Uno method 834*cdf0e10cSrcweir // System::String* sMethodName= mapUnoString(usMethodName.pData); 835*cdf0e10cSrcweir int indexCliMethod = -1; 836*cdf0e10cSrcweir //If the cli interfaces and their methods are in the same order 837*cdf0e10cSrcweir //as they were declared (inheritance chain and within the interface) 838*cdf0e10cSrcweir //then nUnoFunctionPos should lead to the correct method. However, 839*cdf0e10cSrcweir //the documentation does not say that this ordering is given. 840*cdf0e10cSrcweir if (sMethodName->Equals(m_arInterfaceMethodInfos[nUnoFunctionPos]->Name)) 841*cdf0e10cSrcweir indexCliMethod = nUnoFunctionPos; 842*cdf0e10cSrcweir else 843*cdf0e10cSrcweir { 844*cdf0e10cSrcweir int cMethods = m_arInterfaceMethodInfos->get_Length(); 845*cdf0e10cSrcweir for (int i = 0; i < cMethods; i++) 846*cdf0e10cSrcweir { 847*cdf0e10cSrcweir System::String* cliMethod = m_arInterfaceMethodInfos[i]->Name; 848*cdf0e10cSrcweir if (cliMethod->Equals(sMethodName)) 849*cdf0e10cSrcweir { 850*cdf0e10cSrcweir indexCliMethod = i; 851*cdf0e10cSrcweir break; 852*cdf0e10cSrcweir } 853*cdf0e10cSrcweir } 854*cdf0e10cSrcweir } 855*cdf0e10cSrcweir if (indexCliMethod == -1) 856*cdf0e10cSrcweir { 857*cdf0e10cSrcweir OUStringBuffer buf(256); 858*cdf0e10cSrcweir buf.appendAscii(RTL_CONSTASCII_STRINGPARAM( 859*cdf0e10cSrcweir "[cli_uno bridge] CliProxy::getMethodInfo():" 860*cdf0e10cSrcweir "cli object does not implement interface method: ")); 861*cdf0e10cSrcweir buf.append(usMethodName); 862*cdf0e10cSrcweir throw BridgeRuntimeError(buf.makeStringAndClear()); 863*cdf0e10cSrcweir return 0; 864*cdf0e10cSrcweir } 865*cdf0e10cSrcweir m_arUnoPosToCliPos[nUnoFunctionPos] = indexCliMethod; 866*cdf0e10cSrcweir ret = m_arMethodInfos[indexCliMethod]; 867*cdf0e10cSrcweir } 868*cdf0e10cSrcweir __finally 869*cdf0e10cSrcweir { 870*cdf0e10cSrcweir System::Threading::Monitor::Exit(m_arUnoPosToCliPos); 871*cdf0e10cSrcweir } 872*cdf0e10cSrcweir 873*cdf0e10cSrcweir return ret; 874*cdf0e10cSrcweir } 875*cdf0e10cSrcweir 876*cdf0e10cSrcweir CliProxy::~CliProxy() 877*cdf0e10cSrcweir { 878*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 879*cdf0e10cSrcweir sd::Trace::WriteLine(System::String::Format( 880*cdf0e10cSrcweir new System::String( 881*cdf0e10cSrcweir S"cli uno bridge: Destroying proxy for cli object, " 882*cdf0e10cSrcweir S"id:\n\t{0}\n\t{1}\n"), 883*cdf0e10cSrcweir m_oid, m_type)); 884*cdf0e10cSrcweir #endif 885*cdf0e10cSrcweir CliEnvHolder::g_cli_env->revokeInterface(m_oid, mapUnoType(m_unoType.get())); 886*cdf0e10cSrcweir m_bridge->release(); 887*cdf0e10cSrcweir } 888*cdf0e10cSrcweir 889*cdf0e10cSrcweir uno_Interface* CliProxy::create(Bridge const * bridge, 890*cdf0e10cSrcweir System::Object* cliI, 891*cdf0e10cSrcweir typelib_TypeDescription const* pTD, 892*cdf0e10cSrcweir const rtl::OUString& ousOid) 893*cdf0e10cSrcweir { 894*cdf0e10cSrcweir uno_Interface* proxy= static_cast<uno_Interface*>( 895*cdf0e10cSrcweir new CliProxy(bridge, cliI, pTD, ousOid)); 896*cdf0e10cSrcweir 897*cdf0e10cSrcweir //register proxy with target environment (uno) 898*cdf0e10cSrcweir (*bridge->m_uno_env->registerProxyInterface)( 899*cdf0e10cSrcweir bridge->m_uno_env, 900*cdf0e10cSrcweir reinterpret_cast<void**>(&proxy), 901*cdf0e10cSrcweir cli_proxy_free, 902*cdf0e10cSrcweir ousOid.pData, (typelib_InterfaceTypeDescription*) pTD); 903*cdf0e10cSrcweir //register original interface 904*cdf0e10cSrcweir CliEnvHolder::g_cli_env->registerInterface(cliI, mapUnoString(ousOid.pData), 905*cdf0e10cSrcweir mapUnoType((pTD))); 906*cdf0e10cSrcweir 907*cdf0e10cSrcweir return proxy; 908*cdf0e10cSrcweir } 909*cdf0e10cSrcweir 910*cdf0e10cSrcweir 911*cdf0e10cSrcweir 912*cdf0e10cSrcweir void SAL_CALL CliProxy::uno_DispatchMethod( 913*cdf0e10cSrcweir struct _uno_Interface *, 914*cdf0e10cSrcweir const struct _typelib_TypeDescription *, 915*cdf0e10cSrcweir void *, 916*cdf0e10cSrcweir void **, 917*cdf0e10cSrcweir uno_Any ** ) 918*cdf0e10cSrcweir { 919*cdf0e10cSrcweir } 920*cdf0e10cSrcweir inline void CliProxy::acquire() const 921*cdf0e10cSrcweir { 922*cdf0e10cSrcweir if (1 == osl_incrementInterlockedCount( &m_ref )) 923*cdf0e10cSrcweir { 924*cdf0e10cSrcweir // rebirth of proxy zombie 925*cdf0e10cSrcweir void * that = const_cast< CliProxy * >( this ); 926*cdf0e10cSrcweir // register at uno env 927*cdf0e10cSrcweir (*m_bridge->m_uno_env->registerProxyInterface)( 928*cdf0e10cSrcweir m_bridge->m_uno_env, &that, 929*cdf0e10cSrcweir cli_proxy_free, m_usOid.pData, 930*cdf0e10cSrcweir (typelib_InterfaceTypeDescription *)m_unoType.get() ); 931*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 932*cdf0e10cSrcweir OSL_ASSERT( this == (void const * const)that ); 933*cdf0e10cSrcweir #endif 934*cdf0e10cSrcweir } 935*cdf0e10cSrcweir } 936*cdf0e10cSrcweir //--------------------------------------------------------------------------- 937*cdf0e10cSrcweir inline void CliProxy::release() const 938*cdf0e10cSrcweir { 939*cdf0e10cSrcweir if (0 == osl_decrementInterlockedCount( &m_ref )) 940*cdf0e10cSrcweir { 941*cdf0e10cSrcweir // revoke from uno env on last release, 942*cdf0e10cSrcweir // The proxy can be resurrected if acquire is called before the uno 943*cdf0e10cSrcweir // environment calls cli_proxy_free. cli_proxy_free will 944*cdf0e10cSrcweir //delete the proxy. The environment does not acquire a registered 945*cdf0e10cSrcweir //proxy. 946*cdf0e10cSrcweir (*m_bridge->m_uno_env->revokeInterface)( 947*cdf0e10cSrcweir m_bridge->m_uno_env, const_cast< CliProxy * >( this ) ); 948*cdf0e10cSrcweir } 949*cdf0e10cSrcweir } 950*cdf0e10cSrcweir } 951*cdf0e10cSrcweir 952*cdf0e10cSrcweir 953*cdf0e10cSrcweir 954*cdf0e10cSrcweir 955*cdf0e10cSrcweir extern "C" 956*cdf0e10cSrcweir void SAL_CALL cli_proxy_free( uno_ExtEnvironment *, void * proxy ) 957*cdf0e10cSrcweir SAL_THROW_EXTERN_C() 958*cdf0e10cSrcweir { 959*cdf0e10cSrcweir cli_uno::CliProxy * cliProxy = reinterpret_cast< 960*cdf0e10cSrcweir cli_uno::CliProxy * >( proxy ); 961*cdf0e10cSrcweir 962*cdf0e10cSrcweir delete cliProxy; 963*cdf0e10cSrcweir } 964*cdf0e10cSrcweir 965*cdf0e10cSrcweir extern "C" 966*cdf0e10cSrcweir void SAL_CALL cli_proxy_acquire( uno_Interface * pUnoI ) 967*cdf0e10cSrcweir SAL_THROW_EXTERN_C() 968*cdf0e10cSrcweir { 969*cdf0e10cSrcweir CliProxy const * cliProxy = static_cast< CliProxy const * >( pUnoI ); 970*cdf0e10cSrcweir cliProxy->acquire(); 971*cdf0e10cSrcweir } 972*cdf0e10cSrcweir //----------------------------------------------------------------------------- 973*cdf0e10cSrcweir extern "C" 974*cdf0e10cSrcweir void SAL_CALL cli_proxy_release( uno_Interface * pUnoI ) 975*cdf0e10cSrcweir SAL_THROW_EXTERN_C() 976*cdf0e10cSrcweir { 977*cdf0e10cSrcweir CliProxy * cliProxy = static_cast< CliProxy * >( pUnoI ); 978*cdf0e10cSrcweir cliProxy->release(); 979*cdf0e10cSrcweir } 980*cdf0e10cSrcweir 981*cdf0e10cSrcweir //------------------------------------------------------------------------------ 982*cdf0e10cSrcweir extern "C" 983*cdf0e10cSrcweir 984*cdf0e10cSrcweir void SAL_CALL cli_proxy_dispatch( 985*cdf0e10cSrcweir uno_Interface * pUnoI, typelib_TypeDescription const * member_td, 986*cdf0e10cSrcweir void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) 987*cdf0e10cSrcweir SAL_THROW_EXTERN_C() 988*cdf0e10cSrcweir { 989*cdf0e10cSrcweir CliProxy * proxy = static_cast< CliProxy* >( pUnoI ); 990*cdf0e10cSrcweir try 991*cdf0e10cSrcweir { 992*cdf0e10cSrcweir Bridge const* bridge = proxy->m_bridge; 993*cdf0e10cSrcweir 994*cdf0e10cSrcweir switch (member_td->eTypeClass) 995*cdf0e10cSrcweir { 996*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_ATTRIBUTE: 997*cdf0e10cSrcweir { 998*cdf0e10cSrcweir 999*cdf0e10cSrcweir sal_Int32 member_pos = ((typelib_InterfaceMemberTypeDescription *) 1000*cdf0e10cSrcweir member_td)->nPosition; 1001*cdf0e10cSrcweir typelib_InterfaceTypeDescription * iface_td = 1002*cdf0e10cSrcweir (typelib_InterfaceTypeDescription *)proxy->m_unoType.get(); 1003*cdf0e10cSrcweir OSL_ENSURE( 1004*cdf0e10cSrcweir member_pos < iface_td->nAllMembers, 1005*cdf0e10cSrcweir "### member pos out of range!" ); 1006*cdf0e10cSrcweir sal_Int32 function_pos = 1007*cdf0e10cSrcweir iface_td->pMapMemberIndexToFunctionIndex[ member_pos ]; 1008*cdf0e10cSrcweir OSL_ENSURE( 1009*cdf0e10cSrcweir function_pos < iface_td->nMapFunctionIndexToMemberIndex, 1010*cdf0e10cSrcweir "### illegal function index!" ); 1011*cdf0e10cSrcweir 1012*cdf0e10cSrcweir if (uno_ret) // is getter method 1013*cdf0e10cSrcweir { 1014*cdf0e10cSrcweir OUString const& usAttrName= *(rtl_uString**)& 1015*cdf0e10cSrcweir ((typelib_InterfaceMemberTypeDescription*) member_td) 1016*cdf0e10cSrcweir ->pMemberName; 1017*cdf0e10cSrcweir sr::MethodInfo* info = proxy->getMethodInfo(function_pos, 1018*cdf0e10cSrcweir usAttrName, CliProxy::MK_GET); 1019*cdf0e10cSrcweir bridge->call_cli( 1020*cdf0e10cSrcweir proxy->m_cliI, 1021*cdf0e10cSrcweir info, 1022*cdf0e10cSrcweir ((typelib_InterfaceAttributeTypeDescription *)member_td) 1023*cdf0e10cSrcweir ->pAttributeTypeRef, 1024*cdf0e10cSrcweir 0, 0, // no params 1025*cdf0e10cSrcweir uno_ret, 0, uno_exc ); 1026*cdf0e10cSrcweir } 1027*cdf0e10cSrcweir else // is setter method 1028*cdf0e10cSrcweir { 1029*cdf0e10cSrcweir OUString const& usAttrName= *(rtl_uString**) & 1030*cdf0e10cSrcweir ((typelib_InterfaceMemberTypeDescription*) member_td) 1031*cdf0e10cSrcweir ->pMemberName; 1032*cdf0e10cSrcweir sr::MethodInfo* info = proxy->getMethodInfo(function_pos + 1, 1033*cdf0e10cSrcweir usAttrName, CliProxy::MK_SET); 1034*cdf0e10cSrcweir typelib_MethodParameter param; 1035*cdf0e10cSrcweir param.pTypeRef = 1036*cdf0e10cSrcweir ((typelib_InterfaceAttributeTypeDescription *)member_td) 1037*cdf0e10cSrcweir ->pAttributeTypeRef; 1038*cdf0e10cSrcweir param.bIn = sal_True; 1039*cdf0e10cSrcweir param.bOut = sal_False; 1040*cdf0e10cSrcweir 1041*cdf0e10cSrcweir bridge->call_cli( 1042*cdf0e10cSrcweir proxy->m_cliI, 1043*cdf0e10cSrcweir // set follows get method 1044*cdf0e10cSrcweir info, 1045*cdf0e10cSrcweir 0 /* indicates void return */, ¶m, 1, 1046*cdf0e10cSrcweir 0, uno_args, uno_exc ); 1047*cdf0e10cSrcweir } 1048*cdf0e10cSrcweir break; 1049*cdf0e10cSrcweir } 1050*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_METHOD: 1051*cdf0e10cSrcweir { 1052*cdf0e10cSrcweir sal_Int32 member_pos = ((typelib_InterfaceMemberTypeDescription *) 1053*cdf0e10cSrcweir member_td)->nPosition; 1054*cdf0e10cSrcweir typelib_InterfaceTypeDescription * iface_td = 1055*cdf0e10cSrcweir (typelib_InterfaceTypeDescription *)proxy->m_unoType.get(); 1056*cdf0e10cSrcweir OSL_ENSURE( 1057*cdf0e10cSrcweir member_pos < iface_td->nAllMembers, 1058*cdf0e10cSrcweir "### member pos out of range!" ); 1059*cdf0e10cSrcweir sal_Int32 function_pos = 1060*cdf0e10cSrcweir iface_td->pMapMemberIndexToFunctionIndex[ member_pos ]; 1061*cdf0e10cSrcweir OSL_ENSURE( 1062*cdf0e10cSrcweir function_pos < iface_td->nMapFunctionIndexToMemberIndex, 1063*cdf0e10cSrcweir "### illegal function index!" ); 1064*cdf0e10cSrcweir 1065*cdf0e10cSrcweir switch (function_pos) 1066*cdf0e10cSrcweir { 1067*cdf0e10cSrcweir case 0: // queryInterface() 1068*cdf0e10cSrcweir { 1069*cdf0e10cSrcweir TypeDescr demanded_td( 1070*cdf0e10cSrcweir *reinterpret_cast<typelib_TypeDescriptionReference **>( 1071*cdf0e10cSrcweir uno_args[0])); 1072*cdf0e10cSrcweir if (typelib_TypeClass_INTERFACE 1073*cdf0e10cSrcweir != demanded_td.get()->eTypeClass) 1074*cdf0e10cSrcweir { 1075*cdf0e10cSrcweir throw BridgeRuntimeError( 1076*cdf0e10cSrcweir OUSTR("queryInterface() call demands an INTERFACE type!")); 1077*cdf0e10cSrcweir } 1078*cdf0e10cSrcweir 1079*cdf0e10cSrcweir uno_Interface * pInterface = 0; 1080*cdf0e10cSrcweir (*bridge->m_uno_env->getRegisteredInterface)( 1081*cdf0e10cSrcweir bridge->m_uno_env, 1082*cdf0e10cSrcweir (void **)&pInterface, proxy->m_usOid.pData, 1083*cdf0e10cSrcweir (typelib_InterfaceTypeDescription *)demanded_td.get() ); 1084*cdf0e10cSrcweir 1085*cdf0e10cSrcweir if (0 == pInterface) 1086*cdf0e10cSrcweir { 1087*cdf0e10cSrcweir System::Type* mgdDemandedType = 1088*cdf0e10cSrcweir mapUnoType(demanded_td.get()); 1089*cdf0e10cSrcweir if (mgdDemandedType->IsInstanceOfType( proxy->m_cliI )) 1090*cdf0e10cSrcweir { 1091*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 1092*cdf0e10cSrcweir OUString usOid( 1093*cdf0e10cSrcweir mapCliString( 1094*cdf0e10cSrcweir CliEnvHolder::g_cli_env->getObjectIdentifier( 1095*cdf0e10cSrcweir proxy->m_cliI ))); 1096*cdf0e10cSrcweir OSL_ENSURE(usOid.equals( proxy->m_usOid ), 1097*cdf0e10cSrcweir "### different oids!"); 1098*cdf0e10cSrcweir #endif 1099*cdf0e10cSrcweir uno_Interface* pUnoI = bridge->map_cli2uno( 1100*cdf0e10cSrcweir proxy->m_cliI, demanded_td.get() ); 1101*cdf0e10cSrcweir uno_any_construct( 1102*cdf0e10cSrcweir (uno_Any *)uno_ret, &pUnoI, demanded_td.get(), 0 ); 1103*cdf0e10cSrcweir (*pUnoI->release)( pUnoI ); 1104*cdf0e10cSrcweir } 1105*cdf0e10cSrcweir else // object does not support demanded interface 1106*cdf0e10cSrcweir { 1107*cdf0e10cSrcweir uno_any_construct( (uno_Any *)uno_ret, 0, 0, 0 ); 1108*cdf0e10cSrcweir } 1109*cdf0e10cSrcweir // no excetpion occured 1110*cdf0e10cSrcweir *uno_exc = 0; 1111*cdf0e10cSrcweir } 1112*cdf0e10cSrcweir else 1113*cdf0e10cSrcweir { 1114*cdf0e10cSrcweir uno_any_construct( 1115*cdf0e10cSrcweir reinterpret_cast< uno_Any * >( uno_ret ), 1116*cdf0e10cSrcweir &pInterface, demanded_td.get(), 0 ); 1117*cdf0e10cSrcweir (*pInterface->release)( pInterface ); 1118*cdf0e10cSrcweir *uno_exc = 0; 1119*cdf0e10cSrcweir } 1120*cdf0e10cSrcweir break; 1121*cdf0e10cSrcweir } 1122*cdf0e10cSrcweir case 1: // acquire this proxy 1123*cdf0e10cSrcweir cli_proxy_acquire(proxy); 1124*cdf0e10cSrcweir *uno_exc = 0; 1125*cdf0e10cSrcweir break; 1126*cdf0e10cSrcweir case 2: // release this proxy 1127*cdf0e10cSrcweir cli_proxy_release(proxy); 1128*cdf0e10cSrcweir *uno_exc = 0; 1129*cdf0e10cSrcweir break; 1130*cdf0e10cSrcweir default: // arbitrary method call 1131*cdf0e10cSrcweir { 1132*cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription * method_td = 1133*cdf0e10cSrcweir (typelib_InterfaceMethodTypeDescription *)member_td; 1134*cdf0e10cSrcweir OUString const& usMethodName= *(rtl_uString**) & 1135*cdf0e10cSrcweir ((typelib_InterfaceMemberTypeDescription*) member_td) 1136*cdf0e10cSrcweir ->pMemberName; 1137*cdf0e10cSrcweir 1138*cdf0e10cSrcweir sr::MethodInfo* info = proxy->getMethodInfo(function_pos, 1139*cdf0e10cSrcweir usMethodName, CliProxy::MK_METHOD); 1140*cdf0e10cSrcweir bridge->call_cli( 1141*cdf0e10cSrcweir proxy->m_cliI, 1142*cdf0e10cSrcweir info, 1143*cdf0e10cSrcweir method_td->pReturnTypeRef, method_td->pParams, 1144*cdf0e10cSrcweir method_td->nParams, 1145*cdf0e10cSrcweir uno_ret, uno_args, uno_exc); 1146*cdf0e10cSrcweir return; 1147*cdf0e10cSrcweir } 1148*cdf0e10cSrcweir } 1149*cdf0e10cSrcweir break; 1150*cdf0e10cSrcweir } 1151*cdf0e10cSrcweir default: 1152*cdf0e10cSrcweir { 1153*cdf0e10cSrcweir throw BridgeRuntimeError( 1154*cdf0e10cSrcweir OUSTR("illegal member type description!") ); 1155*cdf0e10cSrcweir } 1156*cdf0e10cSrcweir } 1157*cdf0e10cSrcweir } 1158*cdf0e10cSrcweir catch (BridgeRuntimeError & err) 1159*cdf0e10cSrcweir { 1160*cdf0e10cSrcweir // binary identical struct 1161*cdf0e10cSrcweir ::com::sun::star::uno::RuntimeException exc( 1162*cdf0e10cSrcweir OUSTR("[cli_uno bridge error] ") + err.m_message, 1163*cdf0e10cSrcweir ::com::sun::star::uno::Reference< 1164*cdf0e10cSrcweir ::com::sun::star::uno::XInterface >() ); 1165*cdf0e10cSrcweir ::com::sun::star::uno::Type const & exc_type = ::getCppuType( & exc); 1166*cdf0e10cSrcweir uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0); 1167*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 1 1168*cdf0e10cSrcweir OString cstr_msg(OUStringToOString(exc.Message, 1169*cdf0e10cSrcweir RTL_TEXTENCODING_ASCII_US ) ); 1170*cdf0e10cSrcweir OSL_ENSURE(0, cstr_msg.getStr()); 1171*cdf0e10cSrcweir #endif 1172*cdf0e10cSrcweir } 1173*cdf0e10cSrcweir } 1174*cdf0e10cSrcweir 1175*cdf0e10cSrcweir 1176*cdf0e10cSrcweir 1177*cdf0e10cSrcweir 1178*cdf0e10cSrcweir 1179