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
UnoInterfaceInfo(Bridge const * bridge,uno_Interface * unoI,typelib_InterfaceTypeDescription * td)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 }
~UnoInterfaceInfo()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
UnoInterfaceProxy(Bridge * bridge,uno_Interface * pUnoI,typelib_InterfaceTypeDescription * pTD,const OUString & oid)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
~UnoInterfaceProxy()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
create(Bridge * bridge,uno_Interface * pUnoI,typelib_InterfaceTypeDescription * pTD,const OUString & oid)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
addUnoInterface(uno_Interface * pUnoI,typelib_InterfaceTypeDescription * pTd)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
CanCastTo(System::Type * fromType,System::Object *)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
invokeObject(sc::IDictionary * props,srrm::LogicalCallContext * context,srrm::IMethodCallMessage * mcm)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
findInfo(::System::Type * type)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
Invoke(srrm::IMessage * callmsg)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 */
constructReturnMessage(System::Object * cliReturn,System::Object * args[],typelib_InterfaceMethodTypeDescription * mtd,srrm::IMessage * msg,System::Object * exc)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 //################################################################################
CliProxy(Bridge const * bridge,System::Object * cliI,typelib_TypeDescription const * td,const rtl::OUString & usOid)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
makeMethodInfos()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
getMethodInfo(int nUnoFunctionPos,const rtl::OUString & usMethodName,MethodKind methodKind)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
~CliProxy()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
create(Bridge const * bridge,System::Object * cliI,typelib_TypeDescription const * pTD,const rtl::OUString & ousOid)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
uno_DispatchMethod(struct _uno_Interface *,const struct _typelib_TypeDescription *,void *,void **,uno_Any **)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 }
acquire() const916cdf0e10cSrcweir 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 //---------------------------------------------------------------------------
release() const933cdf0e10cSrcweir 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"
cli_proxy_free(uno_ExtEnvironment *,void * proxy)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"
cli_proxy_acquire(uno_Interface * pUnoI)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"
cli_proxy_release(uno_Interface * pUnoI)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
cli_proxy_dispatch(uno_Interface * pUnoI,typelib_TypeDescription const * member_td,void * uno_ret,void * uno_args[],uno_Any ** uno_exc)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