1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_bridges.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <sal/alloca.h>
28*b1cdbd2cSJim Jagielski 
29*b1cdbd2cSJim Jagielski #include "com/sun/star/uno/RuntimeException.hpp"
30*b1cdbd2cSJim Jagielski 
31*b1cdbd2cSJim Jagielski #include "rtl/ustrbuf.hxx"
32*b1cdbd2cSJim Jagielski 
33*b1cdbd2cSJim Jagielski #include "jni_bridge.h"
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski 
36*b1cdbd2cSJim Jagielski using namespace ::std;
37*b1cdbd2cSJim Jagielski using namespace ::rtl;
38*b1cdbd2cSJim Jagielski 
39*b1cdbd2cSJim Jagielski namespace
40*b1cdbd2cSJim Jagielski {
41*b1cdbd2cSJim Jagielski extern "C"
42*b1cdbd2cSJim Jagielski {
43*b1cdbd2cSJim Jagielski 
44*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------------
45*b1cdbd2cSJim Jagielski void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
46*b1cdbd2cSJim Jagielski     SAL_THROW_EXTERN_C();
47*b1cdbd2cSJim Jagielski 
48*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------------
49*b1cdbd2cSJim Jagielski void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
50*b1cdbd2cSJim Jagielski     SAL_THROW_EXTERN_C();
51*b1cdbd2cSJim Jagielski 
52*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------------
53*b1cdbd2cSJim Jagielski void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
54*b1cdbd2cSJim Jagielski     SAL_THROW_EXTERN_C();
55*b1cdbd2cSJim Jagielski 
56*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------------
57*b1cdbd2cSJim Jagielski void SAL_CALL UNO_proxy_dispatch(
58*b1cdbd2cSJim Jagielski     uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
59*b1cdbd2cSJim Jagielski     void * uno_ret, void * uno_args[], uno_Any ** uno_exc )
60*b1cdbd2cSJim Jagielski     SAL_THROW_EXTERN_C();
61*b1cdbd2cSJim Jagielski }
62*b1cdbd2cSJim Jagielski }
63*b1cdbd2cSJim Jagielski 
64*b1cdbd2cSJim Jagielski namespace jni_uno
65*b1cdbd2cSJim Jagielski {
66*b1cdbd2cSJim Jagielski 
67*b1cdbd2cSJim Jagielski //______________________________________________________________________________
handle_java_exc(JNI_context const & jni,JLocalAutoRef const & jo_exc,uno_Any * uno_exc) const68*b1cdbd2cSJim Jagielski void Bridge::handle_java_exc(
69*b1cdbd2cSJim Jagielski     JNI_context const & jni,
70*b1cdbd2cSJim Jagielski     JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const
71*b1cdbd2cSJim Jagielski {
72*b1cdbd2cSJim Jagielski     OSL_ASSERT( jo_exc.is() );
73*b1cdbd2cSJim Jagielski     if (! jo_exc.is())
74*b1cdbd2cSJim Jagielski     {
75*b1cdbd2cSJim Jagielski         throw BridgeRuntimeError(
76*b1cdbd2cSJim Jagielski             OUSTR("java exception occured, but no java exception available!?") +
77*b1cdbd2cSJim Jagielski             jni.get_stack_trace() );
78*b1cdbd2cSJim Jagielski     }
79*b1cdbd2cSJim Jagielski 
80*b1cdbd2cSJim Jagielski     JLocalAutoRef jo_class( jni, jni->GetObjectClass( jo_exc.get() ) );
81*b1cdbd2cSJim Jagielski     JLocalAutoRef jo_class_name(
82*b1cdbd2cSJim Jagielski         jni, jni->CallObjectMethodA(
83*b1cdbd2cSJim Jagielski             jo_class.get(), m_jni_info->m_method_Class_getName, 0 ) );
84*b1cdbd2cSJim Jagielski     jni.ensure_no_exception();
85*b1cdbd2cSJim Jagielski     OUString exc_name(
86*b1cdbd2cSJim Jagielski         jstring_to_oustring( jni, (jstring) jo_class_name.get() ) );
87*b1cdbd2cSJim Jagielski 
88*b1cdbd2cSJim Jagielski     ::com::sun::star::uno::TypeDescription td( exc_name.pData );
89*b1cdbd2cSJim Jagielski     if (!td.is() || (typelib_TypeClass_EXCEPTION != td.get()->eTypeClass))
90*b1cdbd2cSJim Jagielski     {
91*b1cdbd2cSJim Jagielski         // call toString()
92*b1cdbd2cSJim Jagielski         JLocalAutoRef jo_descr(
93*b1cdbd2cSJim Jagielski             jni, jni->CallObjectMethodA(
94*b1cdbd2cSJim Jagielski                 jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
95*b1cdbd2cSJim Jagielski         jni.ensure_no_exception();
96*b1cdbd2cSJim Jagielski         OUStringBuffer buf( 128 );
97*b1cdbd2cSJim Jagielski         buf.appendAscii(
98*b1cdbd2cSJim Jagielski             RTL_CONSTASCII_STRINGPARAM("non-UNO exception occurred: ") );
99*b1cdbd2cSJim Jagielski         buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
100*b1cdbd2cSJim Jagielski         buf.append( jni.get_stack_trace( jo_exc.get() ) );
101*b1cdbd2cSJim Jagielski         throw BridgeRuntimeError( buf.makeStringAndClear() );
102*b1cdbd2cSJim Jagielski     }
103*b1cdbd2cSJim Jagielski 
104*b1cdbd2cSJim Jagielski     auto_ptr< rtl_mem > uno_data( rtl_mem::allocate( td.get()->nSize ) );
105*b1cdbd2cSJim Jagielski     jvalue val;
106*b1cdbd2cSJim Jagielski     val.l = jo_exc.get();
107*b1cdbd2cSJim Jagielski     map_to_uno(
108*b1cdbd2cSJim Jagielski         jni, uno_data.get(), val, td.get()->pWeakRef, 0,
109*b1cdbd2cSJim Jagielski         false /* no assign */, false /* no out param */ );
110*b1cdbd2cSJim Jagielski 
111*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 0
112*b1cdbd2cSJim Jagielski     // patch Message, append stack trace
113*b1cdbd2cSJim Jagielski     reinterpret_cast< ::com::sun::star::uno::Exception * >(
114*b1cdbd2cSJim Jagielski         uno_data.get() )->Message += jni.get_stack_trace( jo_exc.get() );
115*b1cdbd2cSJim Jagielski #endif
116*b1cdbd2cSJim Jagielski 
117*b1cdbd2cSJim Jagielski     typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
118*b1cdbd2cSJim Jagielski     uno_exc->pType = td.get()->pWeakRef;
119*b1cdbd2cSJim Jagielski     uno_exc->pData = uno_data.release();
120*b1cdbd2cSJim Jagielski 
121*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 1
122*b1cdbd2cSJim Jagielski     OUStringBuffer trace_buf( 128 );
123*b1cdbd2cSJim Jagielski     trace_buf.appendAscii(
124*b1cdbd2cSJim Jagielski         RTL_CONSTASCII_STRINGPARAM("exception occured uno->java: [") );
125*b1cdbd2cSJim Jagielski     trace_buf.append( exc_name );
126*b1cdbd2cSJim Jagielski     trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
127*b1cdbd2cSJim Jagielski     trace_buf.append(
128*b1cdbd2cSJim Jagielski         reinterpret_cast< ::com::sun::star::uno::Exception const * >(
129*b1cdbd2cSJim Jagielski             uno_exc->pData )->Message );
130*b1cdbd2cSJim Jagielski     OString cstr_trace(
131*b1cdbd2cSJim Jagielski         OUStringToOString(
132*b1cdbd2cSJim Jagielski             trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
133*b1cdbd2cSJim Jagielski     OSL_TRACE( cstr_trace.getStr() );
134*b1cdbd2cSJim Jagielski #endif
135*b1cdbd2cSJim Jagielski }
136*b1cdbd2cSJim Jagielski 
137*b1cdbd2cSJim Jagielski //______________________________________________________________________________
call_java(jobject javaI,typelib_InterfaceTypeDescription * iface_td,sal_Int32 local_member_index,sal_Int32 function_pos_offset,typelib_TypeDescriptionReference * return_type,typelib_MethodParameter * params,sal_Int32 nParams,void * uno_ret,void * uno_args[],uno_Any ** uno_exc) const138*b1cdbd2cSJim Jagielski void Bridge::call_java(
139*b1cdbd2cSJim Jagielski     jobject javaI, typelib_InterfaceTypeDescription * iface_td,
140*b1cdbd2cSJim Jagielski     sal_Int32 local_member_index, sal_Int32 function_pos_offset,
141*b1cdbd2cSJim Jagielski     typelib_TypeDescriptionReference * return_type,
142*b1cdbd2cSJim Jagielski     typelib_MethodParameter * params, sal_Int32 nParams,
143*b1cdbd2cSJim Jagielski     void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const
144*b1cdbd2cSJim Jagielski {
145*b1cdbd2cSJim Jagielski     OSL_ASSERT( function_pos_offset == 0 || function_pos_offset == 1 );
146*b1cdbd2cSJim Jagielski 
147*b1cdbd2cSJim Jagielski     JNI_guarded_context jni(
148*b1cdbd2cSJim Jagielski         m_jni_info, reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
149*b1cdbd2cSJim Jagielski             m_java_env->pContext ) );
150*b1cdbd2cSJim Jagielski 
151*b1cdbd2cSJim Jagielski     // assure fully initialized iface_td:
152*b1cdbd2cSJim Jagielski     ::com::sun::star::uno::TypeDescription iface_holder;
153*b1cdbd2cSJim Jagielski     if (! iface_td->aBase.bComplete) {
154*b1cdbd2cSJim Jagielski         iface_holder = ::com::sun::star::uno::TypeDescription(
155*b1cdbd2cSJim Jagielski             reinterpret_cast<typelib_TypeDescription *>(iface_td) );
156*b1cdbd2cSJim Jagielski         iface_holder.makeComplete();
157*b1cdbd2cSJim Jagielski         if (! iface_holder.get()->bComplete) {
158*b1cdbd2cSJim Jagielski             OUStringBuffer buf;
159*b1cdbd2cSJim Jagielski             buf.appendAscii(
160*b1cdbd2cSJim Jagielski                 RTL_CONSTASCII_STRINGPARAM("cannot make type complete: ") );
161*b1cdbd2cSJim Jagielski             buf.append( OUString::unacquired(&iface_holder.get()->pTypeName) );
162*b1cdbd2cSJim Jagielski             buf.append( jni.get_stack_trace() );
163*b1cdbd2cSJim Jagielski             throw BridgeRuntimeError( buf.makeStringAndClear() );
164*b1cdbd2cSJim Jagielski         }
165*b1cdbd2cSJim Jagielski         iface_td = reinterpret_cast<typelib_InterfaceTypeDescription *>(
166*b1cdbd2cSJim Jagielski             iface_holder.get() );
167*b1cdbd2cSJim Jagielski         OSL_ASSERT( iface_td->aBase.eTypeClass == typelib_TypeClass_INTERFACE );
168*b1cdbd2cSJim Jagielski     }
169*b1cdbd2cSJim Jagielski 
170*b1cdbd2cSJim Jagielski     // prepare java args, save param td
171*b1cdbd2cSJim Jagielski #ifdef BROKEN_ALLOCA
172*b1cdbd2cSJim Jagielski     jvalue * java_args = (jvalue *) malloc( sizeof (jvalue) * nParams );
173*b1cdbd2cSJim Jagielski #else
174*b1cdbd2cSJim Jagielski     jvalue * java_args = (jvalue *) alloca( sizeof (jvalue) * nParams );
175*b1cdbd2cSJim Jagielski #endif
176*b1cdbd2cSJim Jagielski 
177*b1cdbd2cSJim Jagielski     sal_Int32 nPos;
178*b1cdbd2cSJim Jagielski     for ( nPos = 0; nPos < nParams; ++nPos )
179*b1cdbd2cSJim Jagielski     {
180*b1cdbd2cSJim Jagielski         try
181*b1cdbd2cSJim Jagielski         {
182*b1cdbd2cSJim Jagielski             typelib_MethodParameter const & param = params[ nPos ];
183*b1cdbd2cSJim Jagielski             java_args[ nPos ].l = 0; // if out: build up array[ 1 ]
184*b1cdbd2cSJim Jagielski             map_to_java(
185*b1cdbd2cSJim Jagielski                 jni, &java_args[ nPos ],
186*b1cdbd2cSJim Jagielski                 uno_args[ nPos ],
187*b1cdbd2cSJim Jagielski                 param.pTypeRef, 0,
188*b1cdbd2cSJim Jagielski                 sal_False != param.bIn /* convert uno value */,
189*b1cdbd2cSJim Jagielski                 sal_False != param.bOut /* build up array[ 1 ] */ );
190*b1cdbd2cSJim Jagielski         }
191*b1cdbd2cSJim Jagielski         catch (...)
192*b1cdbd2cSJim Jagielski         {
193*b1cdbd2cSJim Jagielski             // cleanup
194*b1cdbd2cSJim Jagielski             for ( sal_Int32 n = 0; n < nPos; ++n )
195*b1cdbd2cSJim Jagielski             {
196*b1cdbd2cSJim Jagielski                 typelib_MethodParameter const & param = params[ n ];
197*b1cdbd2cSJim Jagielski                 if (param.bOut ||
198*b1cdbd2cSJim Jagielski                     typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
199*b1cdbd2cSJim Jagielski                 {
200*b1cdbd2cSJim Jagielski                     jni->DeleteLocalRef( java_args[ n ].l );
201*b1cdbd2cSJim Jagielski                 }
202*b1cdbd2cSJim Jagielski             }
203*b1cdbd2cSJim Jagielski #ifdef BROKEN_ALLOCA
204*b1cdbd2cSJim Jagielski 	    free( java_args );
205*b1cdbd2cSJim Jagielski #endif
206*b1cdbd2cSJim Jagielski             throw;
207*b1cdbd2cSJim Jagielski         }
208*b1cdbd2cSJim Jagielski     }
209*b1cdbd2cSJim Jagielski 
210*b1cdbd2cSJim Jagielski     sal_Int32 base_members = iface_td->nAllMembers - iface_td->nMembers;
211*b1cdbd2cSJim Jagielski     OSL_ASSERT( base_members < iface_td->nAllMembers );
212*b1cdbd2cSJim Jagielski     sal_Int32 base_members_function_pos =
213*b1cdbd2cSJim Jagielski         iface_td->pMapMemberIndexToFunctionIndex[ base_members ];
214*b1cdbd2cSJim Jagielski     sal_Int32 member_pos = base_members + local_member_index;
215*b1cdbd2cSJim Jagielski     OSL_ENSURE(
216*b1cdbd2cSJim Jagielski         member_pos < iface_td->nAllMembers, "### member pos out of range!" );
217*b1cdbd2cSJim Jagielski     sal_Int32 function_pos =
218*b1cdbd2cSJim Jagielski         iface_td->pMapMemberIndexToFunctionIndex[ member_pos ]
219*b1cdbd2cSJim Jagielski         + function_pos_offset;
220*b1cdbd2cSJim Jagielski     OSL_ENSURE(
221*b1cdbd2cSJim Jagielski         function_pos >= base_members_function_pos
222*b1cdbd2cSJim Jagielski         && function_pos < iface_td->nMapFunctionIndexToMemberIndex,
223*b1cdbd2cSJim Jagielski         "### illegal function index!" );
224*b1cdbd2cSJim Jagielski     function_pos -= base_members_function_pos;
225*b1cdbd2cSJim Jagielski 
226*b1cdbd2cSJim Jagielski     JNI_interface_type_info const * info =
227*b1cdbd2cSJim Jagielski         static_cast< JNI_interface_type_info const * >(
228*b1cdbd2cSJim Jagielski             m_jni_info->get_type_info( jni, &iface_td->aBase ) );
229*b1cdbd2cSJim Jagielski     jmethodID method_id = info->m_methods[ function_pos ];
230*b1cdbd2cSJim Jagielski 
231*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 1
232*b1cdbd2cSJim Jagielski     OUStringBuffer trace_buf( 128 );
233*b1cdbd2cSJim Jagielski     trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("calling ") );
234*b1cdbd2cSJim Jagielski     JLocalAutoRef jo_method(
235*b1cdbd2cSJim Jagielski         jni, jni->ToReflectedMethod( info->m_class, method_id, JNI_FALSE ) );
236*b1cdbd2cSJim Jagielski     jni.ensure_no_exception();
237*b1cdbd2cSJim Jagielski     JLocalAutoRef jo_descr(
238*b1cdbd2cSJim Jagielski         jni, jni->CallObjectMethodA(
239*b1cdbd2cSJim Jagielski             jo_method.get(), m_jni_info->m_method_Object_toString, 0 ) );
240*b1cdbd2cSJim Jagielski     jni.ensure_no_exception();
241*b1cdbd2cSJim Jagielski     trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
242*b1cdbd2cSJim Jagielski     trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on ") );
243*b1cdbd2cSJim Jagielski     jo_descr.reset(
244*b1cdbd2cSJim Jagielski         jni->CallObjectMethodA(
245*b1cdbd2cSJim Jagielski             javaI, m_jni_info->m_method_Object_toString, 0 ) );
246*b1cdbd2cSJim Jagielski     jni.ensure_no_exception();
247*b1cdbd2cSJim Jagielski     trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
248*b1cdbd2cSJim Jagielski     trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (") );
249*b1cdbd2cSJim Jagielski     JLocalAutoRef jo_class( jni, jni->GetObjectClass( javaI ) );
250*b1cdbd2cSJim Jagielski     jo_descr.reset(
251*b1cdbd2cSJim Jagielski         jni->CallObjectMethodA(
252*b1cdbd2cSJim Jagielski             jo_class.get(), m_jni_info->m_method_Object_toString, 0 ) );
253*b1cdbd2cSJim Jagielski     jni.ensure_no_exception();
254*b1cdbd2cSJim Jagielski     trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
255*b1cdbd2cSJim Jagielski     trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(")") );
256*b1cdbd2cSJim Jagielski     OString cstr_trace(
257*b1cdbd2cSJim Jagielski         OUStringToOString(
258*b1cdbd2cSJim Jagielski             trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
259*b1cdbd2cSJim Jagielski     OSL_TRACE( cstr_trace.getStr() );
260*b1cdbd2cSJim Jagielski #endif
261*b1cdbd2cSJim Jagielski 
262*b1cdbd2cSJim Jagielski     // complex return value
263*b1cdbd2cSJim Jagielski     JLocalAutoRef java_ret( jni );
264*b1cdbd2cSJim Jagielski 
265*b1cdbd2cSJim Jagielski     switch (return_type->eTypeClass)
266*b1cdbd2cSJim Jagielski     {
267*b1cdbd2cSJim Jagielski     case typelib_TypeClass_VOID:
268*b1cdbd2cSJim Jagielski         jni->CallVoidMethodA( javaI, method_id, java_args );
269*b1cdbd2cSJim Jagielski         break;
270*b1cdbd2cSJim Jagielski     case typelib_TypeClass_CHAR:
271*b1cdbd2cSJim Jagielski         *(sal_Unicode *)uno_ret =
272*b1cdbd2cSJim Jagielski             jni->CallCharMethodA( javaI, method_id, java_args );
273*b1cdbd2cSJim Jagielski         break;
274*b1cdbd2cSJim Jagielski     case typelib_TypeClass_BOOLEAN:
275*b1cdbd2cSJim Jagielski         *(sal_Bool *)uno_ret =
276*b1cdbd2cSJim Jagielski             jni->CallBooleanMethodA( javaI, method_id, java_args );
277*b1cdbd2cSJim Jagielski         break;
278*b1cdbd2cSJim Jagielski     case typelib_TypeClass_BYTE:
279*b1cdbd2cSJim Jagielski         *(sal_Int8 *)uno_ret =
280*b1cdbd2cSJim Jagielski             jni->CallByteMethodA( javaI, method_id, java_args );
281*b1cdbd2cSJim Jagielski         break;
282*b1cdbd2cSJim Jagielski     case typelib_TypeClass_SHORT:
283*b1cdbd2cSJim Jagielski     case typelib_TypeClass_UNSIGNED_SHORT:
284*b1cdbd2cSJim Jagielski         *(sal_Int16 *)uno_ret =
285*b1cdbd2cSJim Jagielski             jni->CallShortMethodA( javaI, method_id, java_args );
286*b1cdbd2cSJim Jagielski         break;
287*b1cdbd2cSJim Jagielski     case typelib_TypeClass_LONG:
288*b1cdbd2cSJim Jagielski     case typelib_TypeClass_UNSIGNED_LONG:
289*b1cdbd2cSJim Jagielski         *(sal_Int32 *)uno_ret =
290*b1cdbd2cSJim Jagielski             jni->CallIntMethodA( javaI, method_id, java_args );
291*b1cdbd2cSJim Jagielski         break;
292*b1cdbd2cSJim Jagielski     case typelib_TypeClass_HYPER:
293*b1cdbd2cSJim Jagielski     case typelib_TypeClass_UNSIGNED_HYPER:
294*b1cdbd2cSJim Jagielski         *(sal_Int64 *)uno_ret =
295*b1cdbd2cSJim Jagielski             jni->CallLongMethodA( javaI, method_id, java_args );
296*b1cdbd2cSJim Jagielski         break;
297*b1cdbd2cSJim Jagielski     case typelib_TypeClass_FLOAT:
298*b1cdbd2cSJim Jagielski         *(float *)uno_ret =
299*b1cdbd2cSJim Jagielski             jni->CallFloatMethodA( javaI, method_id, java_args );
300*b1cdbd2cSJim Jagielski         break;
301*b1cdbd2cSJim Jagielski     case typelib_TypeClass_DOUBLE:
302*b1cdbd2cSJim Jagielski         *(double *)uno_ret =
303*b1cdbd2cSJim Jagielski             jni->CallDoubleMethodA( javaI, method_id, java_args );
304*b1cdbd2cSJim Jagielski         break;
305*b1cdbd2cSJim Jagielski     default:
306*b1cdbd2cSJim Jagielski         java_ret.reset(
307*b1cdbd2cSJim Jagielski             jni->CallObjectMethodA( javaI, method_id, java_args ) );
308*b1cdbd2cSJim Jagielski         break;
309*b1cdbd2cSJim Jagielski     }
310*b1cdbd2cSJim Jagielski 
311*b1cdbd2cSJim Jagielski     if (jni->ExceptionCheck())
312*b1cdbd2cSJim Jagielski     {
313*b1cdbd2cSJim Jagielski         JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
314*b1cdbd2cSJim Jagielski         jni->ExceptionClear();
315*b1cdbd2cSJim Jagielski 
316*b1cdbd2cSJim Jagielski         // release temp java local refs
317*b1cdbd2cSJim Jagielski         for ( nPos = 0; nPos < nParams; ++nPos )
318*b1cdbd2cSJim Jagielski         {
319*b1cdbd2cSJim Jagielski             typelib_MethodParameter const & param = params[ nPos ];
320*b1cdbd2cSJim Jagielski             if (param.bOut ||
321*b1cdbd2cSJim Jagielski                 typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
322*b1cdbd2cSJim Jagielski             {
323*b1cdbd2cSJim Jagielski                 jni->DeleteLocalRef( java_args[ nPos ].l );
324*b1cdbd2cSJim Jagielski             }
325*b1cdbd2cSJim Jagielski         }
326*b1cdbd2cSJim Jagielski 
327*b1cdbd2cSJim Jagielski         handle_java_exc( jni, jo_exc, *uno_exc );
328*b1cdbd2cSJim Jagielski     }
329*b1cdbd2cSJim Jagielski     else // no exception
330*b1cdbd2cSJim Jagielski     {
331*b1cdbd2cSJim Jagielski         for ( nPos = 0; nPos < nParams; ++nPos )
332*b1cdbd2cSJim Jagielski         {
333*b1cdbd2cSJim Jagielski             typelib_MethodParameter const & param = params[ nPos ];
334*b1cdbd2cSJim Jagielski             if (param.bOut)
335*b1cdbd2cSJim Jagielski             {
336*b1cdbd2cSJim Jagielski                 try
337*b1cdbd2cSJim Jagielski                 {
338*b1cdbd2cSJim Jagielski                     map_to_uno(
339*b1cdbd2cSJim Jagielski                         jni, uno_args[ nPos ],
340*b1cdbd2cSJim Jagielski                         java_args[ nPos ], param.pTypeRef, 0,
341*b1cdbd2cSJim Jagielski                         sal_False != param.bIn /* assign if inout */,
342*b1cdbd2cSJim Jagielski                         true /* out param */ );
343*b1cdbd2cSJim Jagielski                 }
344*b1cdbd2cSJim Jagielski                 catch (...)
345*b1cdbd2cSJim Jagielski                 {
346*b1cdbd2cSJim Jagielski                     // cleanup uno pure out
347*b1cdbd2cSJim Jagielski                     for ( sal_Int32 n = 0; n < nPos; ++n )
348*b1cdbd2cSJim Jagielski                     {
349*b1cdbd2cSJim Jagielski                         typelib_MethodParameter const & p = params[ n ];
350*b1cdbd2cSJim Jagielski                         if (! p.bIn)
351*b1cdbd2cSJim Jagielski                         {
352*b1cdbd2cSJim Jagielski                             uno_type_destructData(
353*b1cdbd2cSJim Jagielski                                 uno_args[ n ], p.pTypeRef, 0 );
354*b1cdbd2cSJim Jagielski                         }
355*b1cdbd2cSJim Jagielski                     }
356*b1cdbd2cSJim Jagielski                     // cleanup java temp local refs
357*b1cdbd2cSJim Jagielski                     for ( ; nPos < nParams; ++nPos )
358*b1cdbd2cSJim Jagielski                     {
359*b1cdbd2cSJim Jagielski                         typelib_MethodParameter const & p = params[ nPos ];
360*b1cdbd2cSJim Jagielski                         if (p.bOut ||
361*b1cdbd2cSJim Jagielski                             typelib_TypeClass_DOUBLE <
362*b1cdbd2cSJim Jagielski                               p.pTypeRef->eTypeClass)
363*b1cdbd2cSJim Jagielski                         {
364*b1cdbd2cSJim Jagielski                             jni->DeleteLocalRef( java_args[ nPos ].l );
365*b1cdbd2cSJim Jagielski                         }
366*b1cdbd2cSJim Jagielski                     }
367*b1cdbd2cSJim Jagielski #ifdef BROKEN_ALLOCA
368*b1cdbd2cSJim Jagielski 		    free( java_args );
369*b1cdbd2cSJim Jagielski #endif
370*b1cdbd2cSJim Jagielski                     throw;
371*b1cdbd2cSJim Jagielski                 }
372*b1cdbd2cSJim Jagielski                 jni->DeleteLocalRef( java_args[ nPos ].l );
373*b1cdbd2cSJim Jagielski             }
374*b1cdbd2cSJim Jagielski             else // pure temp in param
375*b1cdbd2cSJim Jagielski             {
376*b1cdbd2cSJim Jagielski                 if (typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
377*b1cdbd2cSJim Jagielski                     jni->DeleteLocalRef( java_args[ nPos ].l );
378*b1cdbd2cSJim Jagielski             }
379*b1cdbd2cSJim Jagielski         }
380*b1cdbd2cSJim Jagielski 
381*b1cdbd2cSJim Jagielski         // return value
382*b1cdbd2cSJim Jagielski         if (typelib_TypeClass_DOUBLE < return_type->eTypeClass)
383*b1cdbd2cSJim Jagielski         {
384*b1cdbd2cSJim Jagielski             try
385*b1cdbd2cSJim Jagielski             {
386*b1cdbd2cSJim Jagielski                 jvalue val;
387*b1cdbd2cSJim Jagielski                 val.l = java_ret.get();
388*b1cdbd2cSJim Jagielski                 map_to_uno(
389*b1cdbd2cSJim Jagielski                     jni, uno_ret, val, return_type, 0,
390*b1cdbd2cSJim Jagielski                     false /* no assign */, false /* no out param */ );
391*b1cdbd2cSJim Jagielski             }
392*b1cdbd2cSJim Jagielski             catch (...)
393*b1cdbd2cSJim Jagielski             {
394*b1cdbd2cSJim Jagielski                 // cleanup uno pure out
395*b1cdbd2cSJim Jagielski                 for ( sal_Int32 i = 0; i < nParams; ++i )
396*b1cdbd2cSJim Jagielski                 {
397*b1cdbd2cSJim Jagielski                     typelib_MethodParameter const & param = params[ i ];
398*b1cdbd2cSJim Jagielski                     if (! param.bIn)
399*b1cdbd2cSJim Jagielski                     {
400*b1cdbd2cSJim Jagielski                         uno_type_destructData(
401*b1cdbd2cSJim Jagielski                             uno_args[ i ], param.pTypeRef, 0 );
402*b1cdbd2cSJim Jagielski                     }
403*b1cdbd2cSJim Jagielski                 }
404*b1cdbd2cSJim Jagielski #ifdef BROKEN_ALLOCA
405*b1cdbd2cSJim Jagielski 		free( java_args );
406*b1cdbd2cSJim Jagielski #endif
407*b1cdbd2cSJim Jagielski                 throw;
408*b1cdbd2cSJim Jagielski             }
409*b1cdbd2cSJim Jagielski         } // else: already set integral uno return value
410*b1cdbd2cSJim Jagielski 
411*b1cdbd2cSJim Jagielski         // no exception occured
412*b1cdbd2cSJim Jagielski         *uno_exc = 0;
413*b1cdbd2cSJim Jagielski     }
414*b1cdbd2cSJim Jagielski #ifdef BROKEN_ALLOCA
415*b1cdbd2cSJim Jagielski     free( java_args );
416*b1cdbd2cSJim Jagielski #endif
417*b1cdbd2cSJim Jagielski }
418*b1cdbd2cSJim Jagielski 
419*b1cdbd2cSJim Jagielski //==== a uno proxy wrapping a java interface ===================================
420*b1cdbd2cSJim Jagielski struct UNO_proxy : public uno_Interface
421*b1cdbd2cSJim Jagielski {
422*b1cdbd2cSJim Jagielski     mutable oslInterlockedCount         m_ref;
423*b1cdbd2cSJim Jagielski     Bridge const *                      m_bridge;
424*b1cdbd2cSJim Jagielski 
425*b1cdbd2cSJim Jagielski     // mapping information
426*b1cdbd2cSJim Jagielski     jobject                             m_javaI;
427*b1cdbd2cSJim Jagielski     jstring                             m_jo_oid;
428*b1cdbd2cSJim Jagielski     OUString                            m_oid;
429*b1cdbd2cSJim Jagielski     JNI_interface_type_info const *     m_type_info;
430*b1cdbd2cSJim Jagielski 
431*b1cdbd2cSJim Jagielski     inline void acquire() const;
432*b1cdbd2cSJim Jagielski     inline void release() const;
433*b1cdbd2cSJim Jagielski 
434*b1cdbd2cSJim Jagielski     // ctor
435*b1cdbd2cSJim Jagielski     inline UNO_proxy(
436*b1cdbd2cSJim Jagielski         JNI_context const & jni, Bridge const * bridge,
437*b1cdbd2cSJim Jagielski         jobject javaI, jstring jo_oid, OUString const & oid,
438*b1cdbd2cSJim Jagielski         JNI_interface_type_info const * info );
439*b1cdbd2cSJim Jagielski };
440*b1cdbd2cSJim Jagielski 
441*b1cdbd2cSJim Jagielski //______________________________________________________________________________
UNO_proxy(JNI_context const & jni,Bridge const * bridge,jobject javaI,jstring jo_oid,OUString const & oid,JNI_interface_type_info const * info)442*b1cdbd2cSJim Jagielski inline UNO_proxy::UNO_proxy(
443*b1cdbd2cSJim Jagielski     JNI_context const & jni, Bridge const * bridge,
444*b1cdbd2cSJim Jagielski     jobject javaI, jstring jo_oid, OUString const & oid,
445*b1cdbd2cSJim Jagielski     JNI_interface_type_info const * info )
446*b1cdbd2cSJim Jagielski     : m_ref( 1 ),
447*b1cdbd2cSJim Jagielski       m_oid( oid ),
448*b1cdbd2cSJim Jagielski       m_type_info( info )
449*b1cdbd2cSJim Jagielski {
450*b1cdbd2cSJim Jagielski     JNI_info const * jni_info = bridge->m_jni_info;
451*b1cdbd2cSJim Jagielski     JLocalAutoRef jo_string_array(
452*b1cdbd2cSJim Jagielski         jni, jni->NewObjectArray( 1, jni_info->m_class_String, jo_oid ) );
453*b1cdbd2cSJim Jagielski     jni.ensure_no_exception();
454*b1cdbd2cSJim Jagielski     jvalue args[ 3 ];
455*b1cdbd2cSJim Jagielski     args[ 0 ].l = javaI;
456*b1cdbd2cSJim Jagielski     args[ 1 ].l = jo_string_array.get();
457*b1cdbd2cSJim Jagielski     args[ 2 ].l = info->m_type;
458*b1cdbd2cSJim Jagielski     jobject jo_iface = jni->CallObjectMethodA(
459*b1cdbd2cSJim Jagielski         jni_info->m_object_java_env,
460*b1cdbd2cSJim Jagielski         jni_info->m_method_IEnvironment_registerInterface, args );
461*b1cdbd2cSJim Jagielski     jni.ensure_no_exception();
462*b1cdbd2cSJim Jagielski 
463*b1cdbd2cSJim Jagielski     m_javaI = jni->NewGlobalRef( jo_iface );
464*b1cdbd2cSJim Jagielski     m_jo_oid = (jstring) jni->NewGlobalRef( jo_oid );
465*b1cdbd2cSJim Jagielski     bridge->acquire();
466*b1cdbd2cSJim Jagielski     m_bridge = bridge;
467*b1cdbd2cSJim Jagielski 
468*b1cdbd2cSJim Jagielski     // uno_Interface
469*b1cdbd2cSJim Jagielski     uno_Interface::acquire = UNO_proxy_acquire;
470*b1cdbd2cSJim Jagielski     uno_Interface::release = UNO_proxy_release;
471*b1cdbd2cSJim Jagielski     uno_Interface::pDispatcher = UNO_proxy_dispatch;
472*b1cdbd2cSJim Jagielski }
473*b1cdbd2cSJim Jagielski 
474*b1cdbd2cSJim Jagielski //______________________________________________________________________________
acquire() const475*b1cdbd2cSJim Jagielski inline void UNO_proxy::acquire() const
476*b1cdbd2cSJim Jagielski {
477*b1cdbd2cSJim Jagielski     if (1 == osl_incrementInterlockedCount( &m_ref ))
478*b1cdbd2cSJim Jagielski     {
479*b1cdbd2cSJim Jagielski         // rebirth of proxy zombie
480*b1cdbd2cSJim Jagielski         void * that = const_cast< UNO_proxy * >( this );
481*b1cdbd2cSJim Jagielski         // register at uno env
482*b1cdbd2cSJim Jagielski         (*m_bridge->m_uno_env->registerProxyInterface)(
483*b1cdbd2cSJim Jagielski             m_bridge->m_uno_env, &that,
484*b1cdbd2cSJim Jagielski             UNO_proxy_free, m_oid.pData,
485*b1cdbd2cSJim Jagielski             (typelib_InterfaceTypeDescription *)m_type_info->m_td.get() );
486*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 1
487*b1cdbd2cSJim Jagielski         OSL_ASSERT( this == (void const * const)that );
488*b1cdbd2cSJim Jagielski #endif
489*b1cdbd2cSJim Jagielski     }
490*b1cdbd2cSJim Jagielski }
491*b1cdbd2cSJim Jagielski 
492*b1cdbd2cSJim Jagielski //______________________________________________________________________________
release() const493*b1cdbd2cSJim Jagielski inline void UNO_proxy::release() const
494*b1cdbd2cSJim Jagielski {
495*b1cdbd2cSJim Jagielski     if (0 == osl_decrementInterlockedCount( &m_ref ))
496*b1cdbd2cSJim Jagielski     {
497*b1cdbd2cSJim Jagielski         // revoke from uno env on last release
498*b1cdbd2cSJim Jagielski         (*m_bridge->m_uno_env->revokeInterface)(
499*b1cdbd2cSJim Jagielski             m_bridge->m_uno_env, const_cast< UNO_proxy * >( this ) );
500*b1cdbd2cSJim Jagielski     }
501*b1cdbd2cSJim Jagielski }
502*b1cdbd2cSJim Jagielski 
503*b1cdbd2cSJim Jagielski 
504*b1cdbd2cSJim Jagielski //______________________________________________________________________________
map_to_uno(JNI_context const & jni,jobject javaI,JNI_interface_type_info const * info) const505*b1cdbd2cSJim Jagielski uno_Interface * Bridge::map_to_uno(
506*b1cdbd2cSJim Jagielski     JNI_context const & jni,
507*b1cdbd2cSJim Jagielski     jobject javaI, JNI_interface_type_info const * info ) const
508*b1cdbd2cSJim Jagielski {
509*b1cdbd2cSJim Jagielski     JLocalAutoRef jo_oid( jni, compute_oid( jni, javaI ) );
510*b1cdbd2cSJim Jagielski     OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
511*b1cdbd2cSJim Jagielski 
512*b1cdbd2cSJim Jagielski     uno_Interface * pUnoI = 0;
513*b1cdbd2cSJim Jagielski     (*m_uno_env->getRegisteredInterface)(
514*b1cdbd2cSJim Jagielski         m_uno_env, (void **)&pUnoI,
515*b1cdbd2cSJim Jagielski         oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
516*b1cdbd2cSJim Jagielski 
517*b1cdbd2cSJim Jagielski     if (0 == pUnoI) // no existing interface, register new proxy
518*b1cdbd2cSJim Jagielski     {
519*b1cdbd2cSJim Jagielski         // refcount initially 1
520*b1cdbd2cSJim Jagielski         pUnoI = new UNO_proxy(
521*b1cdbd2cSJim Jagielski             jni, const_cast< Bridge * >( this ),
522*b1cdbd2cSJim Jagielski             javaI, (jstring) jo_oid.get(), oid, info );
523*b1cdbd2cSJim Jagielski 
524*b1cdbd2cSJim Jagielski         (*m_uno_env->registerProxyInterface)(
525*b1cdbd2cSJim Jagielski             m_uno_env, (void **)&pUnoI,
526*b1cdbd2cSJim Jagielski             UNO_proxy_free,
527*b1cdbd2cSJim Jagielski             oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
528*b1cdbd2cSJim Jagielski     }
529*b1cdbd2cSJim Jagielski     return pUnoI;
530*b1cdbd2cSJim Jagielski }
531*b1cdbd2cSJim Jagielski 
532*b1cdbd2cSJim Jagielski }
533*b1cdbd2cSJim Jagielski 
534*b1cdbd2cSJim Jagielski using namespace ::jni_uno;
535*b1cdbd2cSJim Jagielski 
536*b1cdbd2cSJim Jagielski namespace
537*b1cdbd2cSJim Jagielski {
538*b1cdbd2cSJim Jagielski extern "C"
539*b1cdbd2cSJim Jagielski {
540*b1cdbd2cSJim Jagielski 
541*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------------
UNO_proxy_free(uno_ExtEnvironment * env,void * proxy)542*b1cdbd2cSJim Jagielski void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
543*b1cdbd2cSJim Jagielski     SAL_THROW_EXTERN_C()
544*b1cdbd2cSJim Jagielski {
545*b1cdbd2cSJim Jagielski     UNO_proxy const * that = reinterpret_cast< UNO_proxy const * >( proxy );
546*b1cdbd2cSJim Jagielski     Bridge const * bridge = that->m_bridge;
547*b1cdbd2cSJim Jagielski 
548*b1cdbd2cSJim Jagielski     if ( env != bridge->m_uno_env ) {
549*b1cdbd2cSJim Jagielski         OSL_ASSERT(false);
550*b1cdbd2cSJim Jagielski     }
551*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 1
552*b1cdbd2cSJim Jagielski     OString cstr_msg(
553*b1cdbd2cSJim Jagielski         OUStringToOString(
554*b1cdbd2cSJim Jagielski             OUSTR("freeing binary uno proxy: ") + that->m_oid,
555*b1cdbd2cSJim Jagielski             RTL_TEXTENCODING_ASCII_US ) );
556*b1cdbd2cSJim Jagielski     OSL_TRACE( cstr_msg.getStr() );
557*b1cdbd2cSJim Jagielski #endif
558*b1cdbd2cSJim Jagielski 
559*b1cdbd2cSJim Jagielski     try
560*b1cdbd2cSJim Jagielski     {
561*b1cdbd2cSJim Jagielski         JNI_guarded_context jni(
562*b1cdbd2cSJim Jagielski             bridge->m_jni_info,
563*b1cdbd2cSJim Jagielski             reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
564*b1cdbd2cSJim Jagielski                 bridge->m_java_env->pContext ) );
565*b1cdbd2cSJim Jagielski 
566*b1cdbd2cSJim Jagielski         jni->DeleteGlobalRef( that->m_javaI );
567*b1cdbd2cSJim Jagielski         jni->DeleteGlobalRef( that->m_jo_oid );
568*b1cdbd2cSJim Jagielski     }
569*b1cdbd2cSJim Jagielski     catch (BridgeRuntimeError & err)
570*b1cdbd2cSJim Jagielski     {
571*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 0
572*b1cdbd2cSJim Jagielski         OString cstr_msg2(
573*b1cdbd2cSJim Jagielski             OUStringToOString( err.m_message, RTL_TEXTENCODING_ASCII_US ) );
574*b1cdbd2cSJim Jagielski         OSL_ENSURE( 0, cstr_msg2.getStr() );
575*b1cdbd2cSJim Jagielski #else
576*b1cdbd2cSJim Jagielski         (void) err; // unused
577*b1cdbd2cSJim Jagielski #endif
578*b1cdbd2cSJim Jagielski     }
579*b1cdbd2cSJim Jagielski     catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
580*b1cdbd2cSJim Jagielski     {
581*b1cdbd2cSJim Jagielski         OSL_ENSURE(
582*b1cdbd2cSJim Jagielski             0,
583*b1cdbd2cSJim Jagielski             "[jni_uno bridge error] attaching current thread to java failed!" );
584*b1cdbd2cSJim Jagielski     }
585*b1cdbd2cSJim Jagielski 
586*b1cdbd2cSJim Jagielski     bridge->release();
587*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 1
588*b1cdbd2cSJim Jagielski     *(int *)that = 0xdeadcafe;
589*b1cdbd2cSJim Jagielski #endif
590*b1cdbd2cSJim Jagielski     delete that;
591*b1cdbd2cSJim Jagielski }
592*b1cdbd2cSJim Jagielski 
593*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------------
UNO_proxy_acquire(uno_Interface * pUnoI)594*b1cdbd2cSJim Jagielski void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
595*b1cdbd2cSJim Jagielski     SAL_THROW_EXTERN_C()
596*b1cdbd2cSJim Jagielski {
597*b1cdbd2cSJim Jagielski     UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
598*b1cdbd2cSJim Jagielski     that->acquire();
599*b1cdbd2cSJim Jagielski }
600*b1cdbd2cSJim Jagielski 
601*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------------
UNO_proxy_release(uno_Interface * pUnoI)602*b1cdbd2cSJim Jagielski void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
603*b1cdbd2cSJim Jagielski     SAL_THROW_EXTERN_C()
604*b1cdbd2cSJim Jagielski {
605*b1cdbd2cSJim Jagielski     UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
606*b1cdbd2cSJim Jagielski     that->release();
607*b1cdbd2cSJim Jagielski }
608*b1cdbd2cSJim Jagielski 
609*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------------
UNO_proxy_dispatch(uno_Interface * pUnoI,typelib_TypeDescription const * member_td,void * uno_ret,void * uno_args[],uno_Any ** uno_exc)610*b1cdbd2cSJim Jagielski void SAL_CALL UNO_proxy_dispatch(
611*b1cdbd2cSJim Jagielski     uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
612*b1cdbd2cSJim Jagielski     void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
613*b1cdbd2cSJim Jagielski     SAL_THROW_EXTERN_C()
614*b1cdbd2cSJim Jagielski {
615*b1cdbd2cSJim Jagielski     UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
616*b1cdbd2cSJim Jagielski     Bridge const * bridge = that->m_bridge;
617*b1cdbd2cSJim Jagielski 
618*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 1
619*b1cdbd2cSJim Jagielski     OUStringBuffer trace_buf( 64 );
620*b1cdbd2cSJim Jagielski     trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno->java call: ") );
621*b1cdbd2cSJim Jagielski     trace_buf.append( OUString::unacquired( &member_td->pTypeName ) );
622*b1cdbd2cSJim Jagielski     trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
623*b1cdbd2cSJim Jagielski     trace_buf.append( that->m_oid );
624*b1cdbd2cSJim Jagielski     OString cstr_msg(
625*b1cdbd2cSJim Jagielski         OUStringToOString(
626*b1cdbd2cSJim Jagielski             trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
627*b1cdbd2cSJim Jagielski     OSL_TRACE( cstr_msg.getStr() );
628*b1cdbd2cSJim Jagielski #endif
629*b1cdbd2cSJim Jagielski 
630*b1cdbd2cSJim Jagielski     try
631*b1cdbd2cSJim Jagielski     {
632*b1cdbd2cSJim Jagielski         switch (member_td->eTypeClass)
633*b1cdbd2cSJim Jagielski         {
634*b1cdbd2cSJim Jagielski         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
635*b1cdbd2cSJim Jagielski         {
636*b1cdbd2cSJim Jagielski             typelib_InterfaceAttributeTypeDescription const * attrib_td =
637*b1cdbd2cSJim Jagielski                 reinterpret_cast<
638*b1cdbd2cSJim Jagielski                 typelib_InterfaceAttributeTypeDescription const * >(
639*b1cdbd2cSJim Jagielski                     member_td );
640*b1cdbd2cSJim Jagielski             com::sun::star::uno::TypeDescription attrib_holder;
641*b1cdbd2cSJim Jagielski             while ( attrib_td->pBaseRef != 0 ) {
642*b1cdbd2cSJim Jagielski                 attrib_holder = com::sun::star::uno::TypeDescription(
643*b1cdbd2cSJim Jagielski                     attrib_td->pBaseRef );
644*b1cdbd2cSJim Jagielski                 OSL_ASSERT(
645*b1cdbd2cSJim Jagielski                     attrib_holder.get()->eTypeClass
646*b1cdbd2cSJim Jagielski                     == typelib_TypeClass_INTERFACE_ATTRIBUTE );
647*b1cdbd2cSJim Jagielski                 attrib_td = reinterpret_cast<
648*b1cdbd2cSJim Jagielski                     typelib_InterfaceAttributeTypeDescription * >(
649*b1cdbd2cSJim Jagielski                         attrib_holder.get() );
650*b1cdbd2cSJim Jagielski             }
651*b1cdbd2cSJim Jagielski             typelib_InterfaceTypeDescription * iface_td = attrib_td->pInterface;
652*b1cdbd2cSJim Jagielski 
653*b1cdbd2cSJim Jagielski             if (0 == uno_ret) // is setter method
654*b1cdbd2cSJim Jagielski             {
655*b1cdbd2cSJim Jagielski                 typelib_MethodParameter param;
656*b1cdbd2cSJim Jagielski                 param.pTypeRef = attrib_td->pAttributeTypeRef;
657*b1cdbd2cSJim Jagielski                 param.bIn = sal_True;
658*b1cdbd2cSJim Jagielski                 param.bOut = sal_False;
659*b1cdbd2cSJim Jagielski 
660*b1cdbd2cSJim Jagielski                 bridge->call_java(
661*b1cdbd2cSJim Jagielski                     that->m_javaI, iface_td,
662*b1cdbd2cSJim Jagielski                     attrib_td->nIndex, 1, // get, then set method
663*b1cdbd2cSJim Jagielski                     bridge->m_jni_info->m_void_type.getTypeLibType(),
664*b1cdbd2cSJim Jagielski                     &param, 1,
665*b1cdbd2cSJim Jagielski                     0, uno_args, uno_exc );
666*b1cdbd2cSJim Jagielski             }
667*b1cdbd2cSJim Jagielski             else // is getter method
668*b1cdbd2cSJim Jagielski             {
669*b1cdbd2cSJim Jagielski                 bridge->call_java(
670*b1cdbd2cSJim Jagielski                     that->m_javaI, iface_td, attrib_td->nIndex, 0,
671*b1cdbd2cSJim Jagielski                     attrib_td->pAttributeTypeRef,
672*b1cdbd2cSJim Jagielski                     0, 0, // no params
673*b1cdbd2cSJim Jagielski                     uno_ret, 0, uno_exc );
674*b1cdbd2cSJim Jagielski             }
675*b1cdbd2cSJim Jagielski             break;
676*b1cdbd2cSJim Jagielski         }
677*b1cdbd2cSJim Jagielski         case typelib_TypeClass_INTERFACE_METHOD:
678*b1cdbd2cSJim Jagielski         {
679*b1cdbd2cSJim Jagielski             typelib_InterfaceMethodTypeDescription const * method_td =
680*b1cdbd2cSJim Jagielski                 reinterpret_cast<
681*b1cdbd2cSJim Jagielski                 typelib_InterfaceMethodTypeDescription const * >(
682*b1cdbd2cSJim Jagielski                     member_td );
683*b1cdbd2cSJim Jagielski             com::sun::star::uno::TypeDescription method_holder;
684*b1cdbd2cSJim Jagielski             while ( method_td->pBaseRef != 0 ) {
685*b1cdbd2cSJim Jagielski                 method_holder = com::sun::star::uno::TypeDescription(
686*b1cdbd2cSJim Jagielski                     method_td->pBaseRef );
687*b1cdbd2cSJim Jagielski                 OSL_ASSERT(
688*b1cdbd2cSJim Jagielski                     method_holder.get()->eTypeClass
689*b1cdbd2cSJim Jagielski                     == typelib_TypeClass_INTERFACE_METHOD );
690*b1cdbd2cSJim Jagielski                 method_td = reinterpret_cast<
691*b1cdbd2cSJim Jagielski                     typelib_InterfaceMethodTypeDescription * >(
692*b1cdbd2cSJim Jagielski                         method_holder.get() );
693*b1cdbd2cSJim Jagielski             }
694*b1cdbd2cSJim Jagielski             typelib_InterfaceTypeDescription * iface_td = method_td->pInterface;
695*b1cdbd2cSJim Jagielski 
696*b1cdbd2cSJim Jagielski             switch ( method_td->aBase.nPosition )
697*b1cdbd2cSJim Jagielski             {
698*b1cdbd2cSJim Jagielski             case 0: // queryInterface()
699*b1cdbd2cSJim Jagielski             {
700*b1cdbd2cSJim Jagielski                 TypeDescr demanded_td(
701*b1cdbd2cSJim Jagielski                     *reinterpret_cast< typelib_TypeDescriptionReference ** >(
702*b1cdbd2cSJim Jagielski                         uno_args[ 0 ] ) );
703*b1cdbd2cSJim Jagielski                 if (typelib_TypeClass_INTERFACE !=
704*b1cdbd2cSJim Jagielski                       demanded_td.get()->eTypeClass)
705*b1cdbd2cSJim Jagielski                 {
706*b1cdbd2cSJim Jagielski                     throw BridgeRuntimeError(
707*b1cdbd2cSJim Jagielski                         OUSTR("queryInterface() call demands "
708*b1cdbd2cSJim Jagielski                               "an INTERFACE type!") );
709*b1cdbd2cSJim Jagielski                 }
710*b1cdbd2cSJim Jagielski 
711*b1cdbd2cSJim Jagielski                 uno_Interface * pInterface = 0;
712*b1cdbd2cSJim Jagielski                 (*bridge->m_uno_env->getRegisteredInterface)(
713*b1cdbd2cSJim Jagielski                     bridge->m_uno_env,
714*b1cdbd2cSJim Jagielski                     (void **) &pInterface, that->m_oid.pData,
715*b1cdbd2cSJim Jagielski                     (typelib_InterfaceTypeDescription *)demanded_td.get() );
716*b1cdbd2cSJim Jagielski 
717*b1cdbd2cSJim Jagielski                 if (0 == pInterface)
718*b1cdbd2cSJim Jagielski                 {
719*b1cdbd2cSJim Jagielski                     JNI_info const * jni_info = bridge->m_jni_info;
720*b1cdbd2cSJim Jagielski                     JNI_guarded_context jni(
721*b1cdbd2cSJim Jagielski                         jni_info,
722*b1cdbd2cSJim Jagielski                         reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
723*b1cdbd2cSJim Jagielski                             bridge->m_java_env->pContext ) );
724*b1cdbd2cSJim Jagielski 
725*b1cdbd2cSJim Jagielski                     JNI_interface_type_info const * info =
726*b1cdbd2cSJim Jagielski                         static_cast< JNI_interface_type_info const * >(
727*b1cdbd2cSJim Jagielski                             jni_info->get_type_info( jni, demanded_td.get() ) );
728*b1cdbd2cSJim Jagielski 
729*b1cdbd2cSJim Jagielski                     jvalue args[ 2 ];
730*b1cdbd2cSJim Jagielski                     args[ 0 ].l = info->m_type;
731*b1cdbd2cSJim Jagielski                     args[ 1 ].l = that->m_javaI;
732*b1cdbd2cSJim Jagielski 
733*b1cdbd2cSJim Jagielski                     JLocalAutoRef jo_ret(
734*b1cdbd2cSJim Jagielski                         jni, jni->CallStaticObjectMethodA(
735*b1cdbd2cSJim Jagielski                             jni_info->m_class_UnoRuntime,
736*b1cdbd2cSJim Jagielski                             jni_info->m_method_UnoRuntime_queryInterface,
737*b1cdbd2cSJim Jagielski                             args ) );
738*b1cdbd2cSJim Jagielski 
739*b1cdbd2cSJim Jagielski                     if (jni->ExceptionCheck())
740*b1cdbd2cSJim Jagielski                     {
741*b1cdbd2cSJim Jagielski                         JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
742*b1cdbd2cSJim Jagielski                         jni->ExceptionClear();
743*b1cdbd2cSJim Jagielski                         bridge->handle_java_exc( jni, jo_exc, *uno_exc );
744*b1cdbd2cSJim Jagielski                     }
745*b1cdbd2cSJim Jagielski                     else
746*b1cdbd2cSJim Jagielski                     {
747*b1cdbd2cSJim Jagielski                         if (jo_ret.is())
748*b1cdbd2cSJim Jagielski                         {
749*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 0
750*b1cdbd2cSJim Jagielski                             JLocalAutoRef jo_oid(
751*b1cdbd2cSJim Jagielski                                 jni, compute_oid( jni, jo_ret.get() ) );
752*b1cdbd2cSJim Jagielski                             OUString oid( jstring_to_oustring(
753*b1cdbd2cSJim Jagielski                                               jni, (jstring) jo_oid.get() ) );
754*b1cdbd2cSJim Jagielski                             OSL_ENSURE(
755*b1cdbd2cSJim Jagielski                                 oid.equals( that->m_oid ),
756*b1cdbd2cSJim Jagielski                                 "### different oids!" );
757*b1cdbd2cSJim Jagielski #endif
758*b1cdbd2cSJim Jagielski                             // refcount initially 1
759*b1cdbd2cSJim Jagielski                             uno_Interface * pUnoI2 = new UNO_proxy(
760*b1cdbd2cSJim Jagielski                                 jni, bridge, jo_ret.get(),
761*b1cdbd2cSJim Jagielski                                 that->m_jo_oid, that->m_oid, info );
762*b1cdbd2cSJim Jagielski 
763*b1cdbd2cSJim Jagielski                             (*bridge->m_uno_env->registerProxyInterface)(
764*b1cdbd2cSJim Jagielski                                 bridge->m_uno_env,
765*b1cdbd2cSJim Jagielski                                 (void **) &pUnoI2,
766*b1cdbd2cSJim Jagielski                                 UNO_proxy_free, that->m_oid.pData,
767*b1cdbd2cSJim Jagielski                                 reinterpret_cast<
768*b1cdbd2cSJim Jagielski                                   typelib_InterfaceTypeDescription * >(
769*b1cdbd2cSJim Jagielski                                       info->m_td.get() ) );
770*b1cdbd2cSJim Jagielski 
771*b1cdbd2cSJim Jagielski                             uno_any_construct(
772*b1cdbd2cSJim Jagielski                                 (uno_Any *)uno_ret, &pUnoI2,
773*b1cdbd2cSJim Jagielski                                 demanded_td.get(), 0 );
774*b1cdbd2cSJim Jagielski                             (*pUnoI2->release)( pUnoI2 );
775*b1cdbd2cSJim Jagielski                         }
776*b1cdbd2cSJim Jagielski                         else // object does not support demanded interface
777*b1cdbd2cSJim Jagielski                         {
778*b1cdbd2cSJim Jagielski                             uno_any_construct(
779*b1cdbd2cSJim Jagielski                                 reinterpret_cast< uno_Any * >( uno_ret ),
780*b1cdbd2cSJim Jagielski                                 0, 0, 0 );
781*b1cdbd2cSJim Jagielski                         }
782*b1cdbd2cSJim Jagielski                         // no exception occured
783*b1cdbd2cSJim Jagielski                         *uno_exc = 0;
784*b1cdbd2cSJim Jagielski                     }
785*b1cdbd2cSJim Jagielski                 }
786*b1cdbd2cSJim Jagielski                 else
787*b1cdbd2cSJim Jagielski                 {
788*b1cdbd2cSJim Jagielski                     uno_any_construct(
789*b1cdbd2cSJim Jagielski                         reinterpret_cast< uno_Any * >( uno_ret ),
790*b1cdbd2cSJim Jagielski                         &pInterface, demanded_td.get(), 0 );
791*b1cdbd2cSJim Jagielski                     (*pInterface->release)( pInterface );
792*b1cdbd2cSJim Jagielski                     *uno_exc = 0;
793*b1cdbd2cSJim Jagielski                 }
794*b1cdbd2cSJim Jagielski                 break;
795*b1cdbd2cSJim Jagielski             }
796*b1cdbd2cSJim Jagielski             case 1: // acquire this proxy
797*b1cdbd2cSJim Jagielski                 that->acquire();
798*b1cdbd2cSJim Jagielski                 *uno_exc = 0;
799*b1cdbd2cSJim Jagielski                 break;
800*b1cdbd2cSJim Jagielski             case 2: // release this proxy
801*b1cdbd2cSJim Jagielski                 that->release();
802*b1cdbd2cSJim Jagielski                 *uno_exc = 0;
803*b1cdbd2cSJim Jagielski                 break;
804*b1cdbd2cSJim Jagielski             default: // arbitrary method call
805*b1cdbd2cSJim Jagielski                 bridge->call_java(
806*b1cdbd2cSJim Jagielski                     that->m_javaI, iface_td, method_td->nIndex, 0,
807*b1cdbd2cSJim Jagielski                     method_td->pReturnTypeRef,
808*b1cdbd2cSJim Jagielski                     method_td->pParams, method_td->nParams,
809*b1cdbd2cSJim Jagielski                     uno_ret, uno_args, uno_exc );
810*b1cdbd2cSJim Jagielski                 break;
811*b1cdbd2cSJim Jagielski             }
812*b1cdbd2cSJim Jagielski             break;
813*b1cdbd2cSJim Jagielski         }
814*b1cdbd2cSJim Jagielski         default:
815*b1cdbd2cSJim Jagielski         {
816*b1cdbd2cSJim Jagielski             throw BridgeRuntimeError(
817*b1cdbd2cSJim Jagielski                 OUSTR("illegal member type description!") );
818*b1cdbd2cSJim Jagielski         }
819*b1cdbd2cSJim Jagielski         }
820*b1cdbd2cSJim Jagielski     }
821*b1cdbd2cSJim Jagielski     catch (BridgeRuntimeError & err)
822*b1cdbd2cSJim Jagielski     {
823*b1cdbd2cSJim Jagielski         OUStringBuffer buf( 128 );
824*b1cdbd2cSJim Jagielski         buf.appendAscii(
825*b1cdbd2cSJim Jagielski             RTL_CONSTASCII_STRINGPARAM(
826*b1cdbd2cSJim Jagielski                 "[jni_uno bridge error] UNO calling Java method ") );
827*b1cdbd2cSJim Jagielski         if (typelib_TypeClass_INTERFACE_METHOD == member_td->eTypeClass ||
828*b1cdbd2cSJim Jagielski             typelib_TypeClass_INTERFACE_ATTRIBUTE == member_td->eTypeClass)
829*b1cdbd2cSJim Jagielski         {
830*b1cdbd2cSJim Jagielski             buf.append( OUString::unacquired(
831*b1cdbd2cSJim Jagielski                             &reinterpret_cast<
832*b1cdbd2cSJim Jagielski                             typelib_InterfaceMemberTypeDescription const * >(
833*b1cdbd2cSJim Jagielski                                 member_td )->pMemberName ) );
834*b1cdbd2cSJim Jagielski         }
835*b1cdbd2cSJim Jagielski         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
836*b1cdbd2cSJim Jagielski         buf.append( err.m_message );
837*b1cdbd2cSJim Jagielski         // binary identical struct
838*b1cdbd2cSJim Jagielski         ::com::sun::star::uno::RuntimeException exc(
839*b1cdbd2cSJim Jagielski             buf.makeStringAndClear(),
840*b1cdbd2cSJim Jagielski             ::com::sun::star::uno::Reference<
841*b1cdbd2cSJim Jagielski               ::com::sun::star::uno::XInterface >() );
842*b1cdbd2cSJim Jagielski         ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc );
843*b1cdbd2cSJim Jagielski         uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
844*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 0
845*b1cdbd2cSJim Jagielski         OString cstr_msg2(
846*b1cdbd2cSJim Jagielski             OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
847*b1cdbd2cSJim Jagielski         OSL_TRACE( "%s", cstr_msg2.getStr() );
848*b1cdbd2cSJim Jagielski #endif
849*b1cdbd2cSJim Jagielski     }
850*b1cdbd2cSJim Jagielski     catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
851*b1cdbd2cSJim Jagielski     {
852*b1cdbd2cSJim Jagielski         // binary identical struct
853*b1cdbd2cSJim Jagielski         ::com::sun::star::uno::RuntimeException exc(
854*b1cdbd2cSJim Jagielski             OUSTR("[jni_uno bridge error] attaching current thread "
855*b1cdbd2cSJim Jagielski                   "to java failed!"),
856*b1cdbd2cSJim Jagielski             ::com::sun::star::uno::Reference<
857*b1cdbd2cSJim Jagielski               ::com::sun::star::uno::XInterface >() );
858*b1cdbd2cSJim Jagielski         ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc );
859*b1cdbd2cSJim Jagielski         uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
860*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 0
861*b1cdbd2cSJim Jagielski         OString cstr_msg2(
862*b1cdbd2cSJim Jagielski             OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
863*b1cdbd2cSJim Jagielski         OSL_ENSURE( 0, cstr_msg2.getStr() );
864*b1cdbd2cSJim Jagielski #endif
865*b1cdbd2cSJim Jagielski     }
866*b1cdbd2cSJim Jagielski }
867*b1cdbd2cSJim Jagielski 
868*b1cdbd2cSJim Jagielski }
869*b1cdbd2cSJim Jagielski }
870