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