1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_bridges.hxx"
26 
27 #include "jni_bridge.h"
28 
29 #include "rtl/strbuf.hxx"
30 #include "rtl/ustrbuf.hxx"
31 #include "uno/sequence2.h"
32 
33 
34 using namespace ::std;
35 using namespace ::rtl;
36 
37 namespace jni_uno
38 {
39 
40 //------------------------------------------------------------------------------
seq_allocate(sal_Int32 nElements,sal_Int32 nSize)41 inline rtl_mem * seq_allocate( sal_Int32 nElements, sal_Int32 nSize )
42 {
43     auto_ptr< rtl_mem > seq(
44         rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
45     uno_Sequence * p = (uno_Sequence *)seq.get();
46     p->nRefCount = 1;
47     p->nElements = nElements;
48     return seq.release();
49 }
50 
51 //______________________________________________________________________________
52 namespace {
53 
createDefaultUnoValue(JNI_context const & jni,void * uno_data,typelib_TypeDescriptionReference * type,JNI_type_info const * info,bool assign)54 void createDefaultUnoValue(
55     JNI_context const & jni, void * uno_data,
56     typelib_TypeDescriptionReference * type,
57     JNI_type_info const * info /* maybe 0 */, bool assign)
58 {
59     switch (type->eTypeClass) {
60     case typelib_TypeClass_BOOLEAN:
61         *static_cast< sal_Bool * >(uno_data) = false;
62         break;
63 
64     case typelib_TypeClass_BYTE:
65         *static_cast< sal_Int8 * >(uno_data) = 0;
66         break;
67 
68     case typelib_TypeClass_SHORT:
69         *static_cast< sal_Int16 * >(uno_data) = 0;
70         break;
71 
72     case typelib_TypeClass_UNSIGNED_SHORT:
73         *static_cast< sal_uInt16 * >(uno_data) = 0;
74         break;
75 
76     case typelib_TypeClass_LONG:
77         *static_cast< sal_Int32 * >(uno_data) = 0;
78         break;
79 
80     case typelib_TypeClass_UNSIGNED_LONG:
81         *static_cast< sal_uInt32 * >(uno_data) = 0;
82         break;
83 
84     case typelib_TypeClass_HYPER:
85         *static_cast< sal_Int64 * >(uno_data) = 0;
86         break;
87 
88     case typelib_TypeClass_UNSIGNED_HYPER:
89         *static_cast< sal_uInt64 * >(uno_data) = 0;
90         break;
91 
92     case typelib_TypeClass_FLOAT:
93         *static_cast< float * >(uno_data) = 0;
94         break;
95 
96     case typelib_TypeClass_DOUBLE:
97         *static_cast< double * >(uno_data) = 0;
98         break;
99 
100     case typelib_TypeClass_CHAR:
101         *static_cast< sal_Unicode * >(uno_data) = 0;
102         break;
103 
104     case typelib_TypeClass_STRING:
105         if (!assign) {
106             *static_cast< rtl_uString ** >(uno_data) = 0;
107         }
108         rtl_uString_new(static_cast< rtl_uString ** >(uno_data));
109         break;
110 
111     case typelib_TypeClass_TYPE:
112         if (assign) {
113             typelib_typedescriptionreference_release(
114                 *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
115         }
116         *static_cast< typelib_TypeDescriptionReference ** >(uno_data)
117             = *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
118         OSL_ASSERT(
119             *static_cast< typelib_TypeDescriptionReference ** >(uno_data) != 0);
120         typelib_typedescriptionreference_acquire(
121             *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
122         break;
123 
124     case typelib_TypeClass_ANY:
125         if (assign) {
126             uno_any_destruct(static_cast< uno_Any * >(uno_data), 0);
127         }
128         uno_any_construct(
129             static_cast< uno_Any * >(uno_data), 0,
130             jni.get_info()->m_XInterface_type_info->m_td.get(), 0);
131         break;
132 
133     case typelib_TypeClass_SEQUENCE:
134         {
135             auto_ptr< rtl_mem > seq(seq_allocate(0, 0));
136             if (assign) {
137                 uno_type_destructData(uno_data, type, 0);
138             }
139             *static_cast< uno_Sequence ** >(uno_data)
140                 = reinterpret_cast< uno_Sequence * >(seq.release());
141             break;
142         }
143 
144     case typelib_TypeClass_ENUM:
145         {
146             typelib_TypeDescription * td = 0;
147             TYPELIB_DANGER_GET(&td, type);
148             *static_cast< sal_Int32 * >(uno_data)
149                 = (reinterpret_cast< typelib_EnumTypeDescription * >(td)->
150                    nDefaultEnumValue);
151             TYPELIB_DANGER_RELEASE(td);
152             break;
153         }
154 
155     case typelib_TypeClass_STRUCT:
156         {
157             if (info == 0) {
158                 info = jni.get_info()->get_type_info(jni, type);
159             }
160             JNI_compound_type_info const * comp_info
161                 = static_cast< JNI_compound_type_info const * >(info);
162             typelib_CompoundTypeDescription * comp_td
163                 = reinterpret_cast< typelib_CompoundTypeDescription * >(
164                     comp_info->m_td.get());
165             sal_Int32 nPos = 0;
166             sal_Int32 nMembers = comp_td->nMembers;
167             try {
168                 if (comp_td->pBaseTypeDescription != 0) {
169                     createDefaultUnoValue(
170                         jni, uno_data,
171                         comp_td->pBaseTypeDescription->aBase.pWeakRef,
172                         comp_info->m_base, assign);
173                 }
174                 for (; nPos < nMembers; ++nPos) {
175                     createDefaultUnoValue(
176                         jni,
177                         (static_cast< char * >(uno_data)
178                          + comp_td->pMemberOffsets[nPos]),
179                         comp_td->ppTypeRefs[nPos], 0, assign);
180                 }
181             } catch (...) {
182                 if (!assign) {
183                     for (sal_Int32 i = 0; i < nPos; ++i) {
184                         uno_type_destructData(
185                             (static_cast< char * >(uno_data)
186                              + comp_td->pMemberOffsets[i]),
187                             comp_td->ppTypeRefs[i], 0);
188                     }
189                     if (comp_td->pBaseTypeDescription != 0) {
190                         uno_destructData(
191                             uno_data, &comp_td->pBaseTypeDescription->aBase, 0);
192                     }
193                 }
194                 throw;
195             }
196         }
197         break;
198 
199     case typelib_TypeClass_INTERFACE:
200         if (assign) {
201             uno_Interface * p = *static_cast< uno_Interface ** >(uno_data);
202             if (p != 0) {
203                 (*p->release)(p);
204             }
205         }
206         *static_cast< uno_Interface ** >(uno_data) = 0;
207         break;
208 
209     default:
210         OSL_ASSERT(false);
211         break;
212     }
213 }
214 
215 }
216 
map_to_uno(JNI_context const & jni,void * uno_data,jvalue java_data,typelib_TypeDescriptionReference * type,JNI_type_info const * info,bool assign,bool out_param,bool special_wrapped_integral_types) const217 void Bridge::map_to_uno(
218     JNI_context const & jni,
219     void * uno_data, jvalue java_data,
220     typelib_TypeDescriptionReference * type,
221     JNI_type_info const * info /* maybe 0 */,
222     bool assign, bool out_param,
223     bool special_wrapped_integral_types ) const
224 {
225     OSL_ASSERT(
226         !out_param ||
227         (1 == jni->GetArrayLength( (jarray) java_data.l )) );
228 
229     switch (type->eTypeClass)
230     {
231 	case typelib_TypeClass_CHAR:
232         if (out_param)
233         {
234             jni->GetCharArrayRegion(
235                 (jcharArray) java_data.l, 0, 1, (jchar *) uno_data );
236             jni.ensure_no_exception();
237         }
238         else if (special_wrapped_integral_types)
239         {
240             *(jchar *) uno_data = jni->CallCharMethodA(
241                 java_data.l, m_jni_info->m_method_Character_charValue, 0 );
242             jni.ensure_no_exception();
243         }
244         else
245         {
246             *(jchar *) uno_data = java_data.c;
247         }
248         break;
249 	case typelib_TypeClass_BOOLEAN:
250         if (out_param)
251         {
252             jni->GetBooleanArrayRegion(
253                 (jbooleanArray) java_data.l, 0, 1, (jboolean *) uno_data );
254             jni.ensure_no_exception();
255         }
256         else if (special_wrapped_integral_types)
257         {
258             *(jboolean *) uno_data = jni->CallBooleanMethodA(
259                 java_data.l, m_jni_info->m_method_Boolean_booleanValue, 0 );
260             jni.ensure_no_exception();
261         }
262         else
263         {
264             *(jboolean *) uno_data = java_data.z;
265         }
266         break;
267 	case typelib_TypeClass_BYTE:
268         if (out_param)
269         {
270             jni->GetByteArrayRegion(
271                 (jbyteArray) java_data.l, 0, 1, (jbyte *) uno_data );
272             jni.ensure_no_exception();
273         }
274         else if (special_wrapped_integral_types)
275         {
276             *(jbyte *) uno_data = jni->CallByteMethodA(
277                 java_data.l, m_jni_info->m_method_Byte_byteValue, 0 );
278             jni.ensure_no_exception();
279         }
280         else
281         {
282             *(jbyte *) uno_data = java_data.b;
283         }
284         break;
285 	case typelib_TypeClass_SHORT:
286 	case typelib_TypeClass_UNSIGNED_SHORT:
287         if (out_param)
288         {
289             jni->GetShortArrayRegion(
290                 (jshortArray) java_data.l, 0, 1, (jshort *) uno_data );
291             jni.ensure_no_exception();
292         }
293         else if (special_wrapped_integral_types)
294         {
295             *(jshort *) uno_data = jni->CallShortMethodA(
296                 java_data.l, m_jni_info->m_method_Short_shortValue, 0 );
297             jni.ensure_no_exception();
298         }
299         else
300         {
301             *(jshort *) uno_data = java_data.s;
302         }
303         break;
304 	case typelib_TypeClass_LONG:
305 	case typelib_TypeClass_UNSIGNED_LONG:
306         if (out_param)
307         {
308             jni->GetIntArrayRegion(
309                 (jintArray) java_data.l, 0, 1, (jint *) uno_data );
310             jni.ensure_no_exception();
311         }
312         else if (special_wrapped_integral_types)
313         {
314             *(jint *) uno_data = jni->CallIntMethodA(
315                 java_data.l, m_jni_info->m_method_Integer_intValue, 0 );
316             jni.ensure_no_exception();
317         }
318         else
319         {
320             *(jint *) uno_data = java_data.i;
321         }
322         break;
323 	case typelib_TypeClass_HYPER:
324 	case typelib_TypeClass_UNSIGNED_HYPER:
325         if (out_param)
326         {
327             jni->GetLongArrayRegion(
328                 (jlongArray) java_data.l, 0, 1, (jlong *) uno_data );
329             jni.ensure_no_exception();
330         }
331         else if (special_wrapped_integral_types)
332         {
333             *(jlong *) uno_data = jni->CallLongMethodA(
334                 java_data.l, m_jni_info->m_method_Long_longValue, 0 );
335             jni.ensure_no_exception();
336         }
337         else
338         {
339             *(jlong *) uno_data = java_data.j;
340         }
341         break;
342 	case typelib_TypeClass_FLOAT:
343         if (out_param)
344         {
345             jni->GetFloatArrayRegion(
346                 (jfloatArray) java_data.l, 0, 1, (jfloat *) uno_data );
347             jni.ensure_no_exception();
348         }
349         else if (special_wrapped_integral_types)
350         {
351             *(jfloat *) uno_data = jni->CallFloatMethodA(
352                 java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
353             jni.ensure_no_exception();
354         }
355         else
356         {
357             *(jfloat *) uno_data = java_data.f;
358         }
359         break;
360 	case typelib_TypeClass_DOUBLE:
361         if (out_param)
362         {
363             jni->GetDoubleArrayRegion(
364                 (jdoubleArray) java_data.l, 0, 1, (jdouble *) uno_data );
365             jni.ensure_no_exception();
366         }
367         else if (special_wrapped_integral_types)
368         {
369             *(jdouble *) uno_data = jni->CallDoubleMethodA(
370                 java_data.l, m_jni_info->m_method_Double_doubleValue, 0 );
371             jni.ensure_no_exception();
372         }
373         else
374         {
375             *(jdouble *) uno_data = java_data.d;
376         }
377         break;
378 	case typelib_TypeClass_STRING:
379     {
380         JLocalAutoRef jo_out_holder( jni );
381         if (out_param)
382         {
383             jo_out_holder.reset(
384                 jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
385             jni.ensure_no_exception();
386             java_data.l = jo_out_holder.get();
387         }
388         if (0 == java_data.l)
389         {
390             OUStringBuffer buf( 128 );
391             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
392             buf.append( OUString::unacquired( &type->pTypeName ) );
393             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
394             buf.append( jni.get_stack_trace() );
395             throw BridgeRuntimeError( buf.makeStringAndClear() );
396         }
397         if (! assign)
398             *(rtl_uString **)uno_data = 0;
399         jstring_to_ustring(
400             jni, (rtl_uString **)uno_data, (jstring) java_data.l );
401         break;
402     }
403 	case typelib_TypeClass_TYPE:
404     {
405         JLocalAutoRef jo_out_holder( jni );
406         if (out_param)
407         {
408             jo_out_holder.reset(
409                 jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
410             jni.ensure_no_exception();
411             java_data.l = jo_out_holder.get();
412         }
413         if (0 == java_data.l)
414         {
415             OUStringBuffer buf( 128 );
416             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
417             buf.append( OUString::unacquired( &type->pTypeName ) );
418             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
419             buf.append( jni.get_stack_trace() );
420             throw BridgeRuntimeError( buf.makeStringAndClear() );
421         }
422 
423         // type name
424         JLocalAutoRef jo_type_name(
425             jni, jni->GetObjectField(
426                 java_data.l, m_jni_info->m_field_Type__typeName ) );
427         if (! jo_type_name.is())
428         {
429             OUStringBuffer buf( 128 );
430             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
431             buf.append( OUString::unacquired( &type->pTypeName ) );
432             buf.appendAscii(
433                 RTL_CONSTASCII_STRINGPARAM("] incomplete type object: "
434                                            "no type name!") );
435             buf.append( jni.get_stack_trace() );
436             throw BridgeRuntimeError( buf.makeStringAndClear() );
437         }
438         OUString type_name(
439             jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
440         ::com::sun::star::uno::TypeDescription td( type_name );
441         if (! td.is())
442         {
443             OUStringBuffer buf( 128 );
444             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
445             buf.append( OUString::unacquired( &type->pTypeName ) );
446             buf.appendAscii(
447                 RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") );
448             buf.append( type_name );
449             buf.append( jni.get_stack_trace() );
450             throw BridgeRuntimeError( buf.makeStringAndClear() );
451         }
452         typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
453         if (assign)
454         {
455             typelib_typedescriptionreference_release(
456                 *(typelib_TypeDescriptionReference **)uno_data );
457         }
458         *(typelib_TypeDescriptionReference **)uno_data = td.get()->pWeakRef;
459         break;
460     }
461 	case typelib_TypeClass_ANY:
462     {
463         JLocalAutoRef jo_out_holder( jni );
464         if (out_param)
465         {
466             jo_out_holder.reset(
467                 jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
468             jni.ensure_no_exception();
469             java_data.l = jo_out_holder.get();
470         }
471 
472         uno_Any * pAny = (uno_Any *)uno_data;
473         if (0 == java_data.l) // null-ref maps to XInterface null-ref
474         {
475             if (assign)
476                 uno_any_destruct( pAny, 0 );
477             uno_any_construct(
478                 pAny, 0, m_jni_info->m_XInterface_type_info->m_td.get(), 0 );
479             break;
480         }
481 
482         JLocalAutoRef jo_type( jni );
483         JLocalAutoRef jo_wrapped_holder( jni );
484 
485         if (JNI_FALSE != jni->IsInstanceOf(
486                 java_data.l, m_jni_info->m_class_Any ))
487         {
488             // boxed any
489             jo_type.reset( jni->GetObjectField(
490                                java_data.l, m_jni_info->m_field_Any__type ) );
491             if (! jo_type.is())
492             {
493                 OUStringBuffer buf( 128 );
494                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
495                 buf.append( OUString::unacquired( &type->pTypeName ) );
496                 buf.appendAscii(
497                     RTL_CONSTASCII_STRINGPARAM("] no type set at "
498                                                "com.sun.star.uno.Any!") );
499                 buf.append( jni.get_stack_trace() );
500                 throw BridgeRuntimeError( buf.makeStringAndClear() );
501             }
502             // wrapped value
503             jo_wrapped_holder.reset(
504                 jni->GetObjectField(
505                     java_data.l, m_jni_info->m_field_Any__object ) );
506             java_data.l = jo_wrapped_holder.get();
507         }
508         else
509         {
510             // create type out of class
511             JLocalAutoRef jo_class( jni, jni->GetObjectClass( java_data.l ) );
512             jo_type.reset( create_type( jni, (jclass) jo_class.get() ) );
513 #if OSL_DEBUG_LEVEL > 1
514             {
515             JLocalAutoRef jo_toString(
516                 jni, jni->CallObjectMethodA(
517                     java_data.l, m_jni_info->m_method_Object_toString, 0 ) );
518             jni.ensure_no_exception();
519             OUString toString(
520                 jstring_to_oustring( jni, (jstring) jo_toString.get() ) );
521             }
522 #endif
523         }
524 
525         // get type name
526         JLocalAutoRef jo_type_name(
527             jni, jni->GetObjectField(
528                 jo_type.get(), m_jni_info->m_field_Type__typeName ) );
529         jni.ensure_no_exception();
530         OUString type_name(
531             jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
532 
533         ::com::sun::star::uno::TypeDescription value_td( type_name );
534         if (! value_td.is())
535         {
536             OUStringBuffer buf( 128 );
537             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
538             buf.append( OUString::unacquired( &type->pTypeName ) );
539             buf.appendAscii(
540                 RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") );
541             buf.append( type_name );
542             buf.append( jni.get_stack_trace() );
543             throw BridgeRuntimeError( buf.makeStringAndClear() );
544         }
545         typelib_TypeClass type_class = value_td.get()->eTypeClass;
546 
547         if (assign)
548         {
549             uno_any_destruct( pAny, 0 );
550         }
551         try
552         {
553             switch (type_class)
554             {
555             case typelib_TypeClass_VOID:
556                 pAny->pData = &pAny->pReserved;
557                 break;
558             case typelib_TypeClass_CHAR:
559                 *(jchar *) &pAny->pReserved = jni->CallCharMethodA(
560                     java_data.l, m_jni_info->m_method_Character_charValue, 0 );
561                 jni.ensure_no_exception();
562                 pAny->pData = &pAny->pReserved;
563                 break;
564             case typelib_TypeClass_BOOLEAN:
565                 *(jboolean *) &pAny->pReserved = jni->CallBooleanMethodA(
566                     java_data.l, m_jni_info->m_method_Boolean_booleanValue, 0 );
567                 jni.ensure_no_exception();
568                 pAny->pData = &pAny->pReserved;
569                 break;
570             case typelib_TypeClass_BYTE:
571                 *(jbyte *) &pAny->pReserved = jni->CallByteMethodA(
572                     java_data.l, m_jni_info->m_method_Byte_byteValue, 0 );
573                 jni.ensure_no_exception();
574                 pAny->pData = &pAny->pReserved;
575                 break;
576             case typelib_TypeClass_SHORT:
577             case typelib_TypeClass_UNSIGNED_SHORT:
578                 *(jshort *) &pAny->pReserved = jni->CallShortMethodA(
579                     java_data.l, m_jni_info->m_method_Short_shortValue, 0 );
580                 jni.ensure_no_exception();
581                 pAny->pData = &pAny->pReserved;
582                 break;
583             case typelib_TypeClass_LONG:
584             case typelib_TypeClass_UNSIGNED_LONG:
585                 *(jint *) &pAny->pReserved = jni->CallIntMethodA(
586                     java_data.l, m_jni_info->m_method_Integer_intValue, 0 );
587                 jni.ensure_no_exception();
588                 pAny->pData = &pAny->pReserved;
589                 break;
590             case typelib_TypeClass_HYPER:
591             case typelib_TypeClass_UNSIGNED_HYPER:
592                 if (sizeof (sal_Int64) <= sizeof (void *))
593                 {
594                     *(jlong *) &pAny->pReserved = jni->CallLongMethodA(
595                         java_data.l, m_jni_info->m_method_Long_longValue, 0 );
596                     jni.ensure_no_exception();
597                     pAny->pData = &pAny->pReserved;
598                 }
599                 else
600                 {
601                     auto_ptr< rtl_mem > mem(
602                         rtl_mem::allocate( sizeof (sal_Int64) ) );
603                     *(jlong *) mem.get() = jni->CallLongMethodA(
604                         java_data.l, m_jni_info->m_method_Long_longValue, 0 );
605                     jni.ensure_no_exception();
606                     pAny->pData = mem.release();
607                 }
608                 break;
609             case typelib_TypeClass_FLOAT:
610                 if (sizeof (float) <= sizeof (void *))
611                 {
612                     *(jfloat *) &pAny->pReserved = jni->CallFloatMethodA(
613                         java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
614                     jni.ensure_no_exception();
615                     pAny->pData = &pAny->pReserved;
616                 }
617                 else
618                 {
619                     auto_ptr< rtl_mem > mem(
620                         rtl_mem::allocate( sizeof (float) ) );
621                     *(jfloat *) mem.get() = jni->CallFloatMethodA(
622                         java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
623                     jni.ensure_no_exception();
624                     pAny->pData = mem.release();
625                 }
626                 break;
627             case typelib_TypeClass_DOUBLE:
628                 if (sizeof (double) <= sizeof (void *))
629                 {
630                     *(jdouble *) &pAny->pReserved =
631                         jni->CallDoubleMethodA(
632                             java_data.l,
633                             m_jni_info->m_method_Double_doubleValue, 0 );
634                     jni.ensure_no_exception();
635                     pAny->pData = &pAny->pReserved;
636                 }
637                 else
638                 {
639                     auto_ptr< rtl_mem > mem(
640                         rtl_mem::allocate( sizeof (double) ) );
641                     *(jdouble *) mem.get() =
642                         jni->CallDoubleMethodA(
643                             java_data.l,
644                             m_jni_info->m_method_Double_doubleValue, 0 );
645                     jni.ensure_no_exception();
646                     pAny->pData = mem.release();
647                 }
648                 break;
649             case typelib_TypeClass_STRING:
650                 // opt: anies often contain strings; copy string directly
651                 pAny->pReserved = 0;
652                 jstring_to_ustring(
653                     jni, (rtl_uString **)&pAny->pReserved,
654                     (jstring) java_data.l );
655                 pAny->pData = &pAny->pReserved;
656                 break;
657             case typelib_TypeClass_TYPE:
658             case typelib_TypeClass_ENUM:
659             case typelib_TypeClass_SEQUENCE:
660             case typelib_TypeClass_INTERFACE:
661                 map_to_uno(
662                     jni, &pAny->pReserved, java_data,
663                     value_td.get()->pWeakRef, 0,
664                     false /* no assign */, false /* no out param */ );
665                 pAny->pData = &pAny->pReserved;
666                 break;
667             case typelib_TypeClass_STRUCT:
668             case typelib_TypeClass_EXCEPTION:
669             {
670                 auto_ptr< rtl_mem > mem(
671                     rtl_mem::allocate( value_td.get()->nSize ) );
672                 map_to_uno(
673                     jni, mem.get(), java_data, value_td.get()->pWeakRef, 0,
674                     false /* no assign */, false /* no out param */ );
675                 pAny->pData = mem.release();
676                 break;
677             }
678             default:
679             {
680                 OUStringBuffer buf( 128 );
681                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
682                 buf.append( type_name );
683                 buf.appendAscii(
684                     RTL_CONSTASCII_STRINGPARAM("] unsupported value type "
685                                                "of any!") );
686                 buf.append( jni.get_stack_trace() );
687                 throw BridgeRuntimeError( buf.makeStringAndClear() );
688             }
689             }
690         }
691         catch (...)
692         {
693             if (assign)
694             {
695                 // restore to valid any
696                 uno_any_construct( pAny, 0, 0, 0 );
697             }
698             throw;
699         }
700         typelib_typedescriptionreference_acquire( value_td.get()->pWeakRef );
701         pAny->pType = value_td.get()->pWeakRef;
702         break;
703     }
704 	case typelib_TypeClass_ENUM:
705     {
706         JLocalAutoRef jo_out_holder( jni );
707         if (out_param)
708         {
709             jo_out_holder.reset(
710                 jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
711             jni.ensure_no_exception();
712             java_data.l = jo_out_holder.get();
713         }
714         if (0 == java_data.l)
715         {
716             OUStringBuffer buf( 128 );
717             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
718             buf.append( OUString::unacquired( &type->pTypeName ) );
719             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
720             buf.append( jni.get_stack_trace() );
721             throw BridgeRuntimeError( buf.makeStringAndClear() );
722         }
723 
724         *(jint *) uno_data = jni->GetIntField(
725             java_data.l, m_jni_info->m_field_Enum_m_value );
726         break;
727     }
728 	case typelib_TypeClass_STRUCT:
729 	case typelib_TypeClass_EXCEPTION:
730     {
731         JLocalAutoRef jo_out_holder( jni );
732         if (out_param)
733         {
734             jo_out_holder.reset(
735                 jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
736             jni.ensure_no_exception();
737             java_data.l = jo_out_holder.get();
738         }
739         if (0 == java_data.l)
740         {
741             OUStringBuffer buf( 128 );
742             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
743             buf.append( OUString::unacquired( &type->pTypeName ) );
744             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
745             buf.append( jni.get_stack_trace() );
746             throw BridgeRuntimeError( buf.makeStringAndClear() );
747         }
748 
749         if (0 == info)
750             info = m_jni_info->get_type_info( jni, type );
751         JNI_compound_type_info const * comp_info =
752             static_cast< JNI_compound_type_info const * >( info );
753 
754         typelib_CompoundTypeDescription * comp_td =
755             (typelib_CompoundTypeDescription *)comp_info->m_td.get();
756         bool polymorphic
757             = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
758             && reinterpret_cast< typelib_StructTypeDescription * >(
759                 comp_td)->pParameterizedTypes != 0;
760 
761         sal_Int32 nPos = 0;
762         sal_Int32 nMembers = comp_td->nMembers;
763         try
764         {
765             if (0 != comp_td->pBaseTypeDescription)
766             {
767                 map_to_uno(
768                     jni, uno_data, java_data,
769                     ((typelib_TypeDescription *) comp_td->pBaseTypeDescription)
770                       ->pWeakRef,
771                     comp_info->m_base,
772                     assign, false /* no out param */ );
773             }
774 
775             for ( ; nPos < nMembers; ++nPos )
776             {
777                 void * p = (char *)uno_data + comp_td->pMemberOffsets[ nPos ];
778                 typelib_TypeDescriptionReference * member_type =
779                     comp_td->ppTypeRefs[ nPos ];
780                 jfieldID field_id = comp_info->m_fields[ nPos ];
781                 bool parameterizedType = polymorphic
782                     && reinterpret_cast< typelib_StructTypeDescription * >(
783                         comp_td)->pParameterizedTypes[nPos];
784                 switch (member_type->eTypeClass)
785                 {
786                 case typelib_TypeClass_CHAR:
787                     if (parameterizedType) {
788                         JLocalAutoRef jo(
789                             jni, jni->GetObjectField( java_data.l, field_id ) );
790                         if ( jo.get() == 0 ) {
791                             *(jchar *) p = 0;
792                         } else {
793                             jvalue val;
794                             val.l = jo.get();
795                             map_to_uno(
796                                 jni, p, val, member_type, 0, assign, false,
797                                 true );
798                         }
799                     } else {
800                         *(jchar *) p = jni->GetCharField(
801                             java_data.l, field_id );
802                     }
803                     break;
804                 case typelib_TypeClass_BOOLEAN:
805                     if (parameterizedType) {
806                         JLocalAutoRef jo(
807                             jni, jni->GetObjectField( java_data.l, field_id ) );
808                         if ( jo.get() == 0 ) {
809                             *(jboolean *) p = false;
810                         } else {
811                             jvalue val;
812                             val.l = jo.get();
813                             map_to_uno(
814                                 jni, p, val, member_type, 0, assign, false,
815                                 true );
816                         }
817                     } else {
818                         *(jboolean *) p = jni->GetBooleanField(
819                             java_data.l, field_id );
820                     }
821                     break;
822                 case typelib_TypeClass_BYTE:
823                     if (parameterizedType) {
824                         JLocalAutoRef jo(
825                             jni, jni->GetObjectField( java_data.l, field_id ) );
826                         if ( jo.get() == 0 ) {
827                             *(jbyte *) p = 0;
828                         } else {
829                             jvalue val;
830                             val.l = jo.get();
831                             map_to_uno(
832                                 jni, p, val, member_type, 0, assign, false,
833                                 true );
834                         }
835                     } else {
836                         *(jbyte *) p = jni->GetByteField(
837                             java_data.l, field_id );
838                     }
839                     break;
840                 case typelib_TypeClass_SHORT:
841                 case typelib_TypeClass_UNSIGNED_SHORT:
842                     if (parameterizedType) {
843                         JLocalAutoRef jo(
844                             jni, jni->GetObjectField( java_data.l, field_id ) );
845                         if ( jo.get() == 0 ) {
846                             *(jshort *) p = 0;
847                         } else {
848                             jvalue val;
849                             val.l = jo.get();
850                             map_to_uno(
851                                 jni, p, val, member_type, 0, assign, false,
852                                 true );
853                         }
854                     } else {
855                         *(jshort *) p = jni->GetShortField(
856                             java_data.l, field_id );
857                     }
858                     break;
859                 case typelib_TypeClass_LONG:
860                 case typelib_TypeClass_UNSIGNED_LONG:
861                     if (parameterizedType) {
862                         JLocalAutoRef jo(
863                             jni, jni->GetObjectField( java_data.l, field_id ) );
864                         if ( jo.get() == 0 ) {
865                             *(jint *) p = 0;
866                         } else {
867                             jvalue val;
868                             val.l = jo.get();
869                             map_to_uno(
870                                 jni, p, val, member_type, 0, assign, false,
871                                 true );
872                         }
873                     } else {
874                         *(jint *) p = jni->GetIntField( java_data.l, field_id );
875                     }
876                     break;
877                 case typelib_TypeClass_HYPER:
878                 case typelib_TypeClass_UNSIGNED_HYPER:
879                     if (parameterizedType) {
880                         JLocalAutoRef jo(
881                             jni, jni->GetObjectField( java_data.l, field_id ) );
882                         if ( jo.get() == 0 ) {
883                             *(jlong *) p = 0;
884                         } else {
885                             jvalue val;
886                             val.l = jo.get();
887                             map_to_uno(
888                                 jni, p, val, member_type, 0, assign, false,
889                                 true );
890                         }
891                     } else {
892                         *(jlong *) p = jni->GetLongField(
893                             java_data.l, field_id );
894                     }
895                     break;
896                 case typelib_TypeClass_FLOAT:
897                     if (parameterizedType) {
898                         JLocalAutoRef jo(
899                             jni, jni->GetObjectField( java_data.l, field_id ) );
900                         if ( jo.get() == 0 ) {
901                             *(jfloat *) p = 0;
902                         } else {
903                             jvalue val;
904                             val.l = jo.get();
905                             map_to_uno(
906                                 jni, p, val, member_type, 0, assign, false,
907                                 true );
908                         }
909                     } else {
910                         *(jfloat *) p = jni->GetFloatField(
911                             java_data.l, field_id );
912                     }
913                     break;
914                 case typelib_TypeClass_DOUBLE:
915                     if (parameterizedType) {
916                         JLocalAutoRef jo(
917                             jni, jni->GetObjectField( java_data.l, field_id ) );
918                         if ( jo.get() == 0 ) {
919                             *(jdouble *) p = 0;
920                         } else {
921                             jvalue val;
922                             val.l = jo.get();
923                             map_to_uno(
924                                 jni, p, val, member_type, 0, assign, false,
925                                 true );
926                         }
927                     } else {
928                         *(jdouble *) p = jni->GetDoubleField(
929                             java_data.l, field_id );
930                     }
931                     break;
932                 default:
933                 {
934                     JLocalAutoRef jo_field( jni );
935                     bool checkNull;
936                     if (0 == field_id)
937                     {
938                         // special for Message: call Throwable.getMessage()
939                         OSL_ASSERT(
940                             type_equals(
941                                 type,
942                                 m_jni_info->m_Exception_type.getTypeLibType() )
943                             || type_equals(
944                                 type,
945                                 m_jni_info->m_RuntimeException_type.
946                                 getTypeLibType() ) );
947                         OSL_ASSERT( 0 == nPos ); // first member
948                         // call getMessage()
949                         jo_field.reset(
950                             jni->CallObjectMethodA(
951                                 java_data.l,
952                                 m_jni_info->m_method_Throwable_getMessage, 0 )
953                             );
954                         jni.ensure_no_exception();
955                         checkNull = true;
956                     }
957                     else
958                     {
959                         jo_field.reset(
960                             jni->GetObjectField( java_data.l, field_id ) );
961                         checkNull = parameterizedType;
962                     }
963                     if (checkNull && !jo_field.is()) {
964                         createDefaultUnoValue(jni, p, member_type, 0, assign);
965                     } else {
966                         jvalue val;
967                         val.l = jo_field.get();
968                         map_to_uno(
969                             jni, p, val, member_type, 0,
970                             assign, false /* no out param */ );
971                     }
972                     break;
973                 }
974                 }
975             }
976         }
977         catch (...)
978         {
979 			if (! assign)
980             {
981                 // cleanup
982                 for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
983                 {
984                     void * p =
985                         (char *)uno_data + comp_td->pMemberOffsets[ nCleanup ];
986                     uno_type_destructData(
987                         p, comp_td->ppTypeRefs[ nCleanup ], 0 );
988                 }
989                 if (0 != comp_td->pBaseTypeDescription)
990                 {
991                     uno_destructData(
992                         uno_data,
993                         (typelib_TypeDescription *) comp_td
994                           ->pBaseTypeDescription, 0 );
995                 }
996             }
997             throw;
998         }
999         break;
1000     }
1001 	case typelib_TypeClass_SEQUENCE:
1002     {
1003         JLocalAutoRef jo_out_holder( jni );
1004         if (out_param)
1005         {
1006             jo_out_holder.reset(
1007                 jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
1008             jni.ensure_no_exception();
1009             java_data.l = jo_out_holder.get();
1010         }
1011         if (0 == java_data.l)
1012         {
1013             OUStringBuffer buf( 128 );
1014             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1015             buf.append( OUString::unacquired( &type->pTypeName ) );
1016             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
1017             buf.append( jni.get_stack_trace() );
1018             throw BridgeRuntimeError( buf.makeStringAndClear() );
1019         }
1020 
1021         TypeDescr td( type );
1022         typelib_TypeDescriptionReference * element_type =
1023             ((typelib_IndirectTypeDescription *)td.get())->pType;
1024 
1025         auto_ptr< rtl_mem > seq;
1026         sal_Int32 nElements = jni->GetArrayLength( (jarray) java_data.l );
1027 
1028         switch (element_type->eTypeClass)
1029         {
1030         case typelib_TypeClass_CHAR:
1031             seq.reset( seq_allocate( nElements, sizeof (sal_Unicode) ) );
1032             jni->GetCharArrayRegion(
1033                 (jcharArray) java_data.l, 0, nElements,
1034                 (jchar *) ((uno_Sequence *) seq.get())->elements );
1035             jni.ensure_no_exception();
1036             break;
1037         case typelib_TypeClass_BOOLEAN:
1038             seq.reset( seq_allocate( nElements, sizeof (sal_Bool) ) );
1039             jni->GetBooleanArrayRegion(
1040                 (jbooleanArray) java_data.l, 0, nElements,
1041                 (jboolean *) ((uno_Sequence *) seq.get())->elements );
1042             jni.ensure_no_exception();
1043             break;
1044         case typelib_TypeClass_BYTE:
1045             seq.reset( seq_allocate( nElements, sizeof (sal_Int8) ) );
1046             jni->GetByteArrayRegion(
1047                 (jbyteArray) java_data.l, 0, nElements,
1048                 (jbyte *) ((uno_Sequence *) seq.get())->elements );
1049             jni.ensure_no_exception();
1050             break;
1051         case typelib_TypeClass_SHORT:
1052         case typelib_TypeClass_UNSIGNED_SHORT:
1053             seq.reset( seq_allocate( nElements, sizeof (sal_Int16) ) );
1054             jni->GetShortArrayRegion(
1055                 (jshortArray) java_data.l, 0, nElements,
1056                 (jshort *) ((uno_Sequence *) seq.get())->elements );
1057             jni.ensure_no_exception();
1058             break;
1059         case typelib_TypeClass_LONG:
1060         case typelib_TypeClass_UNSIGNED_LONG:
1061             seq.reset( seq_allocate( nElements, sizeof (sal_Int32) ) );
1062             jni->GetIntArrayRegion(
1063                 (jintArray) java_data.l, 0, nElements,
1064                 (jint *) ((uno_Sequence *) seq.get())->elements );
1065             jni.ensure_no_exception();
1066             break;
1067         case typelib_TypeClass_HYPER:
1068         case typelib_TypeClass_UNSIGNED_HYPER:
1069             seq.reset( seq_allocate( nElements, sizeof (sal_Int64) ) );
1070             jni->GetLongArrayRegion(
1071                 (jlongArray) java_data.l, 0, nElements,
1072                 (jlong *) ((uno_Sequence *) seq.get())->elements );
1073             jni.ensure_no_exception();
1074             break;
1075         case typelib_TypeClass_FLOAT:
1076             seq.reset( seq_allocate( nElements, sizeof (float) ) );
1077             jni->GetFloatArrayRegion(
1078                 (jfloatArray) java_data.l, 0, nElements,
1079                 (jfloat *)((uno_Sequence *)seq.get())->elements );
1080             jni.ensure_no_exception();
1081             break;
1082         case typelib_TypeClass_DOUBLE:
1083             seq.reset( seq_allocate( nElements, sizeof (double) ) );
1084             jni->GetDoubleArrayRegion(
1085                 (jdoubleArray) java_data.l, 0, nElements,
1086                 (jdouble *) ((uno_Sequence *) seq.get())->elements );
1087             jni.ensure_no_exception();
1088             break;
1089         case typelib_TypeClass_STRING:
1090         case typelib_TypeClass_TYPE:
1091         case typelib_TypeClass_ANY:
1092         case typelib_TypeClass_ENUM:
1093         case typelib_TypeClass_STRUCT:
1094         case typelib_TypeClass_EXCEPTION:
1095         case typelib_TypeClass_SEQUENCE:
1096         case typelib_TypeClass_INTERFACE:
1097         {
1098             TypeDescr element_td( element_type );
1099             seq.reset( seq_allocate( nElements, element_td.get()->nSize ) );
1100 
1101             JNI_type_info const * element_info;
1102             if (typelib_TypeClass_STRUCT == element_type->eTypeClass ||
1103                 typelib_TypeClass_EXCEPTION == element_type->eTypeClass ||
1104                 typelib_TypeClass_INTERFACE == element_type->eTypeClass)
1105             {
1106                 element_info =
1107                     m_jni_info->get_type_info( jni, element_td.get() );
1108             }
1109             else
1110             {
1111                 element_info = 0;
1112             }
1113 
1114             for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1115             {
1116                 try
1117                 {
1118                     JLocalAutoRef jo(
1119                         jni, jni->GetObjectArrayElement(
1120                             (jobjectArray) java_data.l, nPos ) );
1121                     jni.ensure_no_exception();
1122                     jvalue val;
1123                     val.l = jo.get();
1124                     void * p =
1125                         ((uno_Sequence *)seq.get())->elements +
1126                         (nPos * element_td.get()->nSize);
1127                     map_to_uno(
1128                         jni, p, val, element_td.get()->pWeakRef, element_info,
1129                         false /* no assign */, false /* no out param */ );
1130                 }
1131                 catch (...)
1132                 {
1133                     // cleanup
1134                     for ( sal_Int32 nCleanPos = 0;
1135                           nCleanPos < nPos; ++nCleanPos )
1136                     {
1137                         void * p =
1138                             ((uno_Sequence *)seq.get())->elements +
1139                             (nCleanPos * element_td.get()->nSize);
1140                         uno_destructData( p, element_td.get(), 0 );
1141                     }
1142                     throw;
1143                 }
1144             }
1145             break;
1146         }
1147         default:
1148         {
1149             OUStringBuffer buf( 128 );
1150             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1151             buf.append( OUString::unacquired( &type->pTypeName ) );
1152             buf.appendAscii(
1153                 RTL_CONSTASCII_STRINGPARAM("] unsupported sequence element"
1154                                            " type: ") );
1155             buf.append( OUString::unacquired( &element_type->pTypeName ) );
1156             buf.append( jni.get_stack_trace() );
1157             throw BridgeRuntimeError( buf.makeStringAndClear() );
1158         }
1159         }
1160 
1161         if (assign)
1162             uno_destructData( uno_data, td.get(), 0 );
1163         *(uno_Sequence **)uno_data = (uno_Sequence *)seq.release();
1164         break;
1165     }
1166 	case typelib_TypeClass_INTERFACE:
1167     {
1168         JLocalAutoRef jo_out_holder( jni );
1169         if (out_param)
1170         {
1171             jo_out_holder.reset(
1172                 jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
1173             jni.ensure_no_exception();
1174             java_data.l = jo_out_holder.get();
1175         }
1176 
1177         if (0 == java_data.l) // null-ref
1178         {
1179             if (assign)
1180             {
1181                 uno_Interface * p = *(uno_Interface **)uno_data;
1182                 if (0 != p)
1183                     (*p->release)( p );
1184             }
1185             *(uno_Interface **)uno_data = 0;
1186         }
1187         else
1188         {
1189             if (0 == info)
1190                 info = m_jni_info->get_type_info( jni, type );
1191             JNI_interface_type_info const * iface_info =
1192                 static_cast< JNI_interface_type_info const * >( info );
1193             uno_Interface * pUnoI = map_to_uno( jni, java_data.l, iface_info );
1194             if (assign)
1195             {
1196                 uno_Interface * p = *(uno_Interface **)uno_data;
1197                 if (0 != p)
1198                     (*p->release)( p );
1199             }
1200             *(uno_Interface **)uno_data = pUnoI;
1201         }
1202         break;
1203     }
1204     default:
1205     {
1206         OUStringBuffer buf( 128 );
1207         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
1208         buf.append( OUString::unacquired( &type->pTypeName ) );
1209         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
1210         buf.append( jni.get_stack_trace() );
1211         throw BridgeRuntimeError( buf.makeStringAndClear() );
1212     }
1213     }
1214 }
1215 
1216 //##############################################################################
1217 
1218 //______________________________________________________________________________
map_to_java(JNI_context const & jni,jvalue * java_data,void const * uno_data,typelib_TypeDescriptionReference * type,JNI_type_info const * info,bool in_param,bool out_param,bool special_wrapped_integral_types) const1219 void Bridge::map_to_java(
1220     JNI_context const & jni,
1221     jvalue * java_data, void const * uno_data,
1222     typelib_TypeDescriptionReference * type,
1223     JNI_type_info const * info /* maybe 0 */,
1224     bool in_param, bool out_param,
1225     bool special_wrapped_integral_types ) const
1226 {
1227     switch (type->eTypeClass)
1228     {
1229     case typelib_TypeClass_CHAR:
1230         if (out_param)
1231         {
1232             if (0 == java_data->l)
1233             {
1234                 JLocalAutoRef jo_ar( jni, jni->NewCharArray( 1 ) );
1235                 jni.ensure_no_exception();
1236                 if (in_param)
1237                 {
1238                     jni->SetCharArrayRegion(
1239                         (jcharArray) jo_ar.get(), 0, 1, (jchar *) uno_data );
1240                     jni.ensure_no_exception();
1241                 }
1242                 java_data->l = jo_ar.release();
1243             }
1244             else
1245             {
1246                 if (in_param)
1247                 {
1248                     jni->SetCharArrayRegion(
1249                         (jcharArray) java_data->l, 0, 1, (jchar *) uno_data );
1250                     jni.ensure_no_exception();
1251                 }
1252             }
1253         }
1254         else if (special_wrapped_integral_types)
1255         {
1256             jvalue arg;
1257             arg.c = *(jchar const *) uno_data;
1258             java_data->l = jni->NewObjectA(
1259                 m_jni_info->m_class_Character,
1260                 m_jni_info->m_ctor_Character_with_char, &arg );
1261             jni.ensure_no_exception();
1262         }
1263         else
1264         {
1265             java_data->c = *(jchar const *) uno_data;
1266         }
1267         break;
1268     case typelib_TypeClass_BOOLEAN:
1269         if (out_param)
1270         {
1271             if (0 == java_data->l)
1272             {
1273                 JLocalAutoRef jo_ar( jni, jni->NewBooleanArray( 1 ) );
1274                 jni.ensure_no_exception();
1275                 if (in_param)
1276                 {
1277                     jni->SetBooleanArrayRegion(
1278                         (jbooleanArray) jo_ar.get(),
1279                         0, 1, (jboolean *) uno_data );
1280                     jni.ensure_no_exception();
1281                 }
1282                 java_data->l = jo_ar.release();
1283             }
1284             else
1285             {
1286                 if (in_param)
1287                 {
1288                     jni->SetBooleanArrayRegion(
1289                         (jbooleanArray) java_data->l,
1290                         0, 1, (jboolean *) uno_data );
1291                     jni.ensure_no_exception();
1292                 }
1293             }
1294         }
1295         else if (special_wrapped_integral_types)
1296         {
1297             jvalue arg;
1298             arg.z = *(jboolean const *) uno_data;
1299             java_data->l = jni->NewObjectA(
1300                 m_jni_info->m_class_Boolean,
1301                 m_jni_info->m_ctor_Boolean_with_boolean, &arg );
1302             jni.ensure_no_exception();
1303         }
1304         else
1305         {
1306             java_data->z = *(jboolean const *) uno_data;
1307         }
1308         break;
1309     case typelib_TypeClass_BYTE:
1310         if (out_param)
1311         {
1312             if (0 == java_data->l)
1313             {
1314                 JLocalAutoRef jo_ar( jni, jni->NewByteArray( 1 ) );
1315                 jni.ensure_no_exception();
1316                 if (in_param)
1317                 {
1318                     jni->SetByteArrayRegion(
1319                         (jbyteArray) jo_ar.get(), 0, 1, (jbyte *) uno_data );
1320                     jni.ensure_no_exception();
1321                 }
1322                 java_data->l = jo_ar.release();
1323             }
1324             else
1325             {
1326                 if (in_param)
1327                 {
1328                     jni->SetByteArrayRegion(
1329                         (jbyteArray) java_data->l, 0, 1, (jbyte *) uno_data );
1330                     jni.ensure_no_exception();
1331                 }
1332             }
1333         }
1334         else if (special_wrapped_integral_types)
1335         {
1336             jvalue arg;
1337             arg.b = *(jbyte const *) uno_data;
1338             java_data->l = jni->NewObjectA(
1339                 m_jni_info->m_class_Byte,
1340                 m_jni_info->m_ctor_Byte_with_byte, &arg );
1341             jni.ensure_no_exception();
1342         }
1343         else
1344         {
1345             java_data->b = *(jbyte const *) uno_data;
1346         }
1347         break;
1348     case typelib_TypeClass_SHORT:
1349     case typelib_TypeClass_UNSIGNED_SHORT:
1350         if (out_param)
1351         {
1352             if (0 == java_data->l)
1353             {
1354                 JLocalAutoRef jo_ar( jni, jni->NewShortArray( 1 ) );
1355                 jni.ensure_no_exception();
1356                 if (in_param)
1357                 {
1358                     jni->SetShortArrayRegion(
1359                         (jshortArray) jo_ar.get(), 0, 1, (jshort *) uno_data );
1360                     jni.ensure_no_exception();
1361                 }
1362                 java_data->l = jo_ar.release();
1363             }
1364             else
1365             {
1366                 if (in_param)
1367                 {
1368                     jni->SetShortArrayRegion(
1369                         (jshortArray) java_data->l, 0, 1, (jshort *) uno_data );
1370                     jni.ensure_no_exception();
1371                 }
1372             }
1373         }
1374         else if (special_wrapped_integral_types)
1375         {
1376             jvalue arg;
1377             arg.s = *(jshort const *) uno_data;
1378             java_data->l = jni->NewObjectA(
1379                 m_jni_info->m_class_Short,
1380                 m_jni_info->m_ctor_Short_with_short, &arg );
1381             jni.ensure_no_exception();
1382         }
1383         else
1384         {
1385             java_data->s = *(jshort const *) uno_data;
1386         }
1387         break;
1388     case typelib_TypeClass_LONG:
1389     case typelib_TypeClass_UNSIGNED_LONG:
1390         if (out_param)
1391         {
1392             if (0 == java_data->l)
1393             {
1394                 JLocalAutoRef jo_ar( jni, jni->NewIntArray( 1 ) );
1395                 jni.ensure_no_exception();
1396                 if (in_param)
1397                 {
1398                     jni->SetIntArrayRegion(
1399                         (jintArray) jo_ar.get(), 0, 1, (jint *) uno_data );
1400                     jni.ensure_no_exception();
1401                 }
1402                 java_data->l = jo_ar.release();
1403             }
1404             else
1405             {
1406                 if (in_param)
1407                 {
1408                     jni->SetIntArrayRegion(
1409                         (jintArray) java_data->l, 0, 1, (jint *) uno_data );
1410                     jni.ensure_no_exception();
1411                 }
1412             }
1413         }
1414         else if (special_wrapped_integral_types)
1415         {
1416             jvalue arg;
1417             arg.i = *(jint const *) uno_data;
1418             java_data->l = jni->NewObjectA(
1419                 m_jni_info->m_class_Integer,
1420                 m_jni_info->m_ctor_Integer_with_int, &arg );
1421             jni.ensure_no_exception();
1422         }
1423         else
1424         {
1425             java_data->i = *(jint const *) uno_data;
1426         }
1427         break;
1428     case typelib_TypeClass_HYPER:
1429     case typelib_TypeClass_UNSIGNED_HYPER:
1430         if (out_param)
1431         {
1432             if (0 == java_data->l)
1433             {
1434                 JLocalAutoRef jo_ar( jni, jni->NewLongArray( 1 ) );
1435                 jni.ensure_no_exception();
1436                 if (in_param)
1437                 {
1438                     jni->SetLongArrayRegion(
1439                         (jlongArray)jo_ar.get(), 0, 1, (jlong *) uno_data );
1440                     jni.ensure_no_exception();
1441                 }
1442                 java_data->l = jo_ar.release();
1443             }
1444             else
1445             {
1446                 if (in_param)
1447                 {
1448                     jni->SetLongArrayRegion(
1449                         (jlongArray)java_data->l, 0, 1, (jlong *) uno_data );
1450                     jni.ensure_no_exception();
1451                 }
1452             }
1453         }
1454         else if (special_wrapped_integral_types)
1455         {
1456             jvalue arg;
1457             arg.j = *(jlong const *) uno_data;
1458             java_data->l = jni->NewObjectA(
1459                 m_jni_info->m_class_Long,
1460                 m_jni_info->m_ctor_Long_with_long, &arg );
1461             jni.ensure_no_exception();
1462         }
1463         else
1464         {
1465             java_data->j = *(jlong const *) uno_data;
1466         }
1467         break;
1468     case typelib_TypeClass_FLOAT:
1469         if (out_param)
1470         {
1471             if (0 == java_data->l)
1472             {
1473                 JLocalAutoRef jo_ar( jni, jni->NewFloatArray( 1 ) );
1474                 jni.ensure_no_exception();
1475                 if (in_param)
1476                 {
1477                     jni->SetFloatArrayRegion(
1478                         (jfloatArray) jo_ar.get(), 0, 1, (jfloat *) uno_data );
1479                     jni.ensure_no_exception();
1480                 }
1481                 java_data->l = jo_ar.release();
1482             }
1483             else
1484             {
1485                 if (in_param)
1486                 {
1487                     jni->SetFloatArrayRegion(
1488                         (jfloatArray) java_data->l, 0, 1, (jfloat *) uno_data );
1489                     jni.ensure_no_exception();
1490                 }
1491             }
1492         }
1493         else if (special_wrapped_integral_types)
1494         {
1495             jvalue arg;
1496             arg.f = *(jfloat const *) uno_data;
1497             java_data->l = jni->NewObjectA(
1498                 m_jni_info->m_class_Float,
1499                 m_jni_info->m_ctor_Float_with_float, &arg );
1500             jni.ensure_no_exception();
1501         }
1502         else
1503         {
1504             java_data->f = *(jfloat const *) uno_data;
1505         }
1506         break;
1507     case typelib_TypeClass_DOUBLE:
1508         if (out_param)
1509         {
1510             if (0 == java_data->l)
1511             {
1512                 JLocalAutoRef jo_ar( jni, jni->NewDoubleArray( 1 ) );
1513                 jni.ensure_no_exception();
1514                 if (in_param)
1515                 {
1516                     jni->SetDoubleArrayRegion(
1517                         (jdoubleArray) jo_ar.get(),
1518                         0, 1, (jdouble *) uno_data );
1519                     jni.ensure_no_exception();
1520                 }
1521                 java_data->l = jo_ar.release();
1522             }
1523             else
1524             {
1525                 if (in_param)
1526                 {
1527                     jni->SetDoubleArrayRegion(
1528                         (jdoubleArray) java_data->l,
1529                         0, 1, (jdouble *) uno_data );
1530                     jni.ensure_no_exception();
1531                 }
1532             }
1533         }
1534         else if (special_wrapped_integral_types)
1535         {
1536             jvalue arg;
1537             arg.d = *(double const *)uno_data;
1538             java_data->l = jni->NewObjectA(
1539                 m_jni_info->m_class_Double,
1540                 m_jni_info->m_ctor_Double_with_double, &arg );
1541             jni.ensure_no_exception();
1542         }
1543         else
1544         {
1545             java_data->d = *(jdouble const *) uno_data;
1546         }
1547         break;
1548     case typelib_TypeClass_STRING:
1549     {
1550         if (out_param)
1551         {
1552             JLocalAutoRef jo_in( jni );
1553             if (in_param)
1554             {
1555                 jo_in.reset(
1556                     ustring_to_jstring(
1557                         jni, *(rtl_uString * const *) uno_data ) );
1558             }
1559             if (0 == java_data->l)
1560             {
1561                 java_data->l = jni->NewObjectArray(
1562                     1, m_jni_info->m_class_String, jo_in.get() );
1563                 jni.ensure_no_exception();
1564             }
1565             else
1566             {
1567                 jni->SetObjectArrayElement(
1568                     (jobjectArray) java_data->l, 0, jo_in.get() );
1569                 jni.ensure_no_exception();
1570             }
1571         }
1572         else
1573         {
1574             OSL_ASSERT( in_param );
1575             java_data->l =
1576                 ustring_to_jstring( jni, *(rtl_uString * const *) uno_data );
1577         }
1578         break;
1579     }
1580     case typelib_TypeClass_TYPE:
1581     {
1582         if (out_param)
1583         {
1584             JLocalAutoRef jo_in( jni );
1585             if (in_param)
1586             {
1587                 jo_in.reset(
1588                     create_type(
1589                         jni,
1590                         *(typelib_TypeDescriptionReference * const *) uno_data )
1591                     );
1592             }
1593             if (0 == java_data->l)
1594             {
1595                 java_data->l = jni->NewObjectArray(
1596                     1, m_jni_info->m_class_Type, jo_in.get() );
1597                 jni.ensure_no_exception();
1598             }
1599             else
1600             {
1601                 jni->SetObjectArrayElement(
1602                     (jobjectArray) java_data->l, 0, jo_in.get() );
1603                 jni.ensure_no_exception();
1604             }
1605         }
1606         else
1607         {
1608             OSL_ASSERT( in_param );
1609             java_data->l =
1610                 create_type(
1611                     jni,
1612                     *(typelib_TypeDescriptionReference * const *) uno_data );
1613         }
1614         break;
1615     }
1616     case typelib_TypeClass_ANY:
1617     {
1618         JLocalAutoRef jo_any( jni );
1619         if (in_param)
1620         {
1621             uno_Any const * pAny = (uno_Any const *)uno_data;
1622 
1623 #if defined BRIDGES_JNI_UNO_FORCE_BOXED_ANY
1624             if (typelib_TypeClass_VOID == pAny->pType->eTypeClass)
1625             {
1626                 jo_any.reset(
1627                     jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) );
1628             }
1629             else
1630             {
1631                 jvalue args[ 2 ];
1632                 map_to_java(
1633                     jni, &args[ 1 ], pAny->pData, pAny->pType, 0,
1634                     true /* in */, false /* no out */,
1635                     true /* create integral wrappers */ );
1636                 jo_any.reset( args[ 1 ].l );
1637                 // build up com.sun.star.uno.Any
1638                 JLocalAutoRef jo_type( jni, create_type( jni, pAny->pType ) );
1639                 args[ 0 ].l = jo_type.get();
1640                 jo_any.reset(
1641                     jni->NewObjectA(
1642                         m_jni_info->m_class_Any,
1643                         m_jni_info->m_ctor_Any_with_Type_Object, args ) );
1644                 jni.ensure_no_exception();
1645             }
1646 #else
1647             switch (pAny->pType->eTypeClass)
1648             {
1649             case typelib_TypeClass_VOID:
1650                 jo_any.reset(
1651                     jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) );
1652                 break;
1653             case typelib_TypeClass_UNSIGNED_SHORT:
1654             {
1655                 jvalue args[ 2 ];
1656                 args[ 0 ].s = *(jshort const *) &pAny->pReserved;
1657                 JLocalAutoRef jo_val(
1658                     jni, jni->NewObjectA(
1659                         m_jni_info->m_class_Short,
1660                         m_jni_info->m_ctor_Short_with_short, args ) );
1661                 jni.ensure_no_exception();
1662                 // box up in com.sun.star.uno.Any
1663                 args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_SHORT;
1664                 args[ 1 ].l = jo_val.get();
1665                 jo_any.reset(
1666                     jni->NewObjectA(
1667                         m_jni_info->m_class_Any,
1668                         m_jni_info->m_ctor_Any_with_Type_Object, args ) );
1669                 jni.ensure_no_exception();
1670                 break;
1671             }
1672             case typelib_TypeClass_UNSIGNED_LONG:
1673             {
1674                 jvalue args[ 2 ];
1675                 args[ 0 ].i = *(jint const *) &pAny->pReserved;
1676                 JLocalAutoRef jo_val(
1677                     jni, jni->NewObjectA(
1678                         m_jni_info->m_class_Integer,
1679                         m_jni_info->m_ctor_Integer_with_int, args ) );
1680                 jni.ensure_no_exception();
1681                 // box up in com.sun.star.uno.Any
1682                 args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_LONG;
1683                 args[ 1 ].l = jo_val.get();
1684                 jo_any.reset(
1685                     jni->NewObjectA(
1686                         m_jni_info->m_class_Any,
1687                         m_jni_info->m_ctor_Any_with_Type_Object, args ) );
1688                 jni.ensure_no_exception();
1689                 break;
1690             }
1691             case typelib_TypeClass_UNSIGNED_HYPER:
1692             {
1693                 jvalue args[ 2 ];
1694                 args[ 0 ].j = *(jlong const *) pAny->pData;
1695                 JLocalAutoRef jo_val(
1696                     jni, jni->NewObjectA(
1697                         m_jni_info->m_class_Long,
1698                         m_jni_info->m_ctor_Long_with_long, args ) );
1699                 jni.ensure_no_exception();
1700                 // box up in com.sun.star.uno.Any
1701                 args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_HYPER;
1702                 args[ 1 ].l = jo_val.get();
1703                 jo_any.reset(
1704                     jni->NewObjectA(
1705                         m_jni_info->m_class_Any,
1706                         m_jni_info->m_ctor_Any_with_Type_Object, args ) );
1707                 jni.ensure_no_exception();
1708                 break;
1709             }
1710             case typelib_TypeClass_STRING: // opt strings
1711                 jo_any.reset( ustring_to_jstring(
1712                                   jni, (rtl_uString *) pAny->pReserved ) );
1713                 break;
1714             case typelib_TypeClass_SEQUENCE:
1715             {
1716                 jvalue java_data2;
1717                 // prefetch sequence td
1718                 TypeDescr seq_td( pAny->pType );
1719                 map_to_java(
1720                     jni, &java_data2, pAny->pData, seq_td.get()->pWeakRef, 0,
1721                     true /* in */, false /* no out */,
1722                     true /* create integral wrappers */ );
1723                 jo_any.reset( java_data2.l );
1724 
1725                 // determine inner element type
1726                 ::com::sun::star::uno::Type element_type(
1727                     ((typelib_IndirectTypeDescription *)seq_td.get())->pType );
1728                 while (typelib_TypeClass_SEQUENCE ==
1729                          element_type.getTypeLibType()->eTypeClass)
1730                 {
1731                     TypeDescr element_td( element_type.getTypeLibType() );
1732                     typelib_typedescriptionreference_assign(
1733                         reinterpret_cast< typelib_TypeDescriptionReference ** >(
1734                             &element_type ),
1735                         ((typelib_IndirectTypeDescription *)element_td.get())
1736                           ->pType );
1737                 }
1738                 // box up only if unsigned element type
1739                 switch (element_type.getTypeLibType()->eTypeClass)
1740                 {
1741                 case typelib_TypeClass_UNSIGNED_SHORT:
1742                 case typelib_TypeClass_UNSIGNED_LONG:
1743                 case typelib_TypeClass_UNSIGNED_HYPER:
1744                 {
1745                     jvalue args[ 2 ];
1746                     JLocalAutoRef jo_type(
1747                         jni, create_type( jni, seq_td.get()->pWeakRef ) );
1748                     args[ 0 ].l = jo_type.get();
1749                     args[ 1 ].l = jo_any.get();
1750                     jo_any.reset(
1751                         jni->NewObjectA(
1752                             m_jni_info->m_class_Any,
1753                             m_jni_info->m_ctor_Any_with_Type_Object, args ) );
1754                     jni.ensure_no_exception();
1755                     break;
1756                 }
1757                 default:
1758                     break;
1759                 }
1760                 break;
1761             }
1762             case typelib_TypeClass_INTERFACE:
1763             {
1764                 uno_Interface * pUnoI = (uno_Interface *)pAny->pReserved;
1765                 if (is_XInterface( pAny->pType ))
1766                 {
1767                     if (0 != pUnoI)
1768                     {
1769                         jo_any.reset(
1770                             map_to_java(
1771                                 jni, pUnoI,
1772                                 m_jni_info->m_XInterface_type_info ) );
1773                     }
1774                     // else: empty XInterface ref maps to null-ref
1775                 }
1776                 else
1777                 {
1778                     JNI_interface_type_info const * iface_info =
1779                         static_cast< JNI_interface_type_info const * >(
1780                             m_jni_info->get_type_info( jni, pAny->pType ) );
1781                     if (0 != pUnoI)
1782                     {
1783                         jo_any.reset( map_to_java( jni, pUnoI, iface_info ) );
1784                     }
1785                     // box up in com.sun.star.uno.Any
1786                     jvalue args[ 2 ];
1787                     args[ 0 ].l = iface_info->m_type;
1788                     args[ 1 ].l = jo_any.get();
1789                     jo_any.reset(
1790                         jni->NewObjectA(
1791                             m_jni_info->m_class_Any,
1792                             m_jni_info->m_ctor_Any_with_Type_Object, args ) );
1793                     jni.ensure_no_exception();
1794                 }
1795                 break;
1796             }
1797             case typelib_TypeClass_STRUCT:
1798             {
1799                 // Do not lose information about type arguments of instantiated
1800                 // polymorphic struct types:
1801                 rtl::OUString const & name = rtl::OUString::unacquired(
1802                     &pAny->pType->pTypeName);
1803                 OSL_ASSERT(!name.isEmpty());
1804                 if (name[name.getLength() - 1] == '>')
1805                 {
1806                     // Box up in com.sun.star.uno.Any:
1807                     JLocalAutoRef jo_type(jni, create_type(jni, pAny->pType));
1808                     jvalue java_data2;
1809                     map_to_java(
1810                         jni, &java_data2, pAny->pData, pAny->pType, 0, true,
1811                         false);
1812                     jo_any.reset(java_data2.l);
1813                     jvalue args[2];
1814                     args[0].l = jo_type.get();
1815                     args[1].l = jo_any.get();
1816                     jo_any.reset(
1817                         jni->NewObjectA(
1818                             m_jni_info->m_class_Any,
1819                             m_jni_info->m_ctor_Any_with_Type_Object, args));
1820                     jni.ensure_no_exception();
1821                     break;
1822                 }
1823                 // fall through
1824             }
1825             default:
1826             {
1827                 jvalue java_data2;
1828                 map_to_java(
1829                     jni, &java_data2, pAny->pData, pAny->pType, 0,
1830                     true /* in */, false /* no out */,
1831                     true /* create integral wrappers */ );
1832                 jo_any.reset( java_data2.l );
1833                 break;
1834             }
1835             }
1836 #endif
1837         }
1838 
1839         if (out_param)
1840         {
1841             if (0 == java_data->l)
1842             {
1843                 java_data->l = jni->NewObjectArray(
1844                     1, m_jni_info->m_class_Object, jo_any.get() );
1845                 jni.ensure_no_exception();
1846             }
1847             else
1848             {
1849                 jni->SetObjectArrayElement(
1850                     (jobjectArray) java_data->l, 0, jo_any.get() );
1851                 jni.ensure_no_exception();
1852             }
1853         }
1854         else
1855         {
1856             java_data->l = jo_any.release();
1857         }
1858         break;
1859     }
1860     case typelib_TypeClass_ENUM:
1861     {
1862         OUString const & type_name = OUString::unacquired( &type->pTypeName );
1863         OString class_name(
1864             OUStringToOString( type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
1865         JLocalAutoRef jo_enum_class(
1866             jni, find_class( jni, class_name.getStr() ) );
1867 
1868         JLocalAutoRef jo_enum( jni );
1869         if (in_param)
1870         {
1871             // call static <enum_class>.fromInt( int )
1872             OStringBuffer sig_buf( 5 + class_name.getLength() );
1873             sig_buf.append( RTL_CONSTASCII_STRINGPARAM("(I)L") );
1874             sig_buf.append( class_name.replace( '.', '/' ) );
1875             sig_buf.append( ';' );
1876             OString sig( sig_buf.makeStringAndClear() );
1877             jmethodID method_id = jni->GetStaticMethodID(
1878                 (jclass) jo_enum_class.get(), "fromInt", sig.getStr() );
1879             jni.ensure_no_exception();
1880             OSL_ASSERT( 0 != method_id );
1881 
1882             jvalue arg;
1883             arg.i = *(jint const *) uno_data;
1884             jo_enum.reset(
1885                 jni->CallStaticObjectMethodA(
1886                     (jclass) jo_enum_class.get(), method_id, &arg ) );
1887             jni.ensure_no_exception();
1888         }
1889         if (out_param)
1890         {
1891             if (0 == java_data->l)
1892             {
1893                 java_data->l = jni->NewObjectArray(
1894                     1, (jclass) jo_enum_class.get(), jo_enum.get() );
1895                 jni.ensure_no_exception();
1896             }
1897             else
1898             {
1899                 jni->SetObjectArrayElement(
1900                     (jobjectArray) java_data->l, 0, jo_enum.get() );
1901                 jni.ensure_no_exception();
1902             }
1903         }
1904         else
1905         {
1906             java_data->l = jo_enum.release();
1907         }
1908         break;
1909     }
1910     case typelib_TypeClass_STRUCT:
1911     case typelib_TypeClass_EXCEPTION:
1912     {
1913         if (0 == info)
1914             info = m_jni_info->get_type_info( jni, type );
1915         JNI_compound_type_info const * comp_info =
1916             static_cast< JNI_compound_type_info const * >( info );
1917 
1918         JLocalAutoRef jo_comp( jni );
1919         if (in_param)
1920         {
1921             if (typelib_TypeClass_EXCEPTION == type->eTypeClass)
1922             {
1923                 JLocalAutoRef jo_message(
1924                     jni, ustring_to_jstring( jni, *(rtl_uString **)uno_data ) );
1925                 jvalue arg;
1926                 arg.l = jo_message.get();
1927                 jo_comp.reset(
1928                     jni->NewObjectA(
1929                         comp_info->m_class, comp_info->m_exc_ctor, &arg ) );
1930                 jni.ensure_no_exception();
1931             }
1932             else
1933             {
1934                 jo_comp.reset( jni->AllocObject( comp_info->m_class ) );
1935                 jni.ensure_no_exception();
1936             }
1937 
1938             for ( JNI_compound_type_info const * linfo = comp_info;
1939                   0 != linfo;
1940                   linfo = static_cast< JNI_compound_type_info const * >(
1941                       linfo->m_base ) )
1942             {
1943                 typelib_CompoundTypeDescription * comp_td =
1944                     (typelib_CompoundTypeDescription *)linfo->m_td.get();
1945                 typelib_TypeDescriptionReference ** ppMemberTypeRefs =
1946                     comp_td->ppTypeRefs;
1947                 sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
1948                 bool polymorphic
1949                     = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
1950                     && reinterpret_cast< typelib_StructTypeDescription * >(
1951                         comp_td)->pParameterizedTypes != 0;
1952                 for ( sal_Int32 nPos = comp_td->nMembers; nPos--; )
1953                 {
1954                     jfieldID field_id = linfo->m_fields[ nPos ];
1955                     if (0 != field_id)
1956                     {
1957                         void const * p =
1958                             (char const *)uno_data + pMemberOffsets[ nPos ];
1959                         typelib_TypeDescriptionReference * member_type =
1960                             ppMemberTypeRefs[ nPos ];
1961                         bool parameterizedType = polymorphic
1962                             && (reinterpret_cast<
1963                                 typelib_StructTypeDescription * >(comp_td)->
1964                                 pParameterizedTypes[nPos]);
1965                         switch (member_type->eTypeClass)
1966                         {
1967                         case typelib_TypeClass_CHAR:
1968                             if (parameterizedType) {
1969                                 jvalue arg;
1970                                 arg.c = *(jchar const *) p;
1971                                 JLocalAutoRef jo(
1972                                     jni,
1973                                     jni->NewObjectA(
1974                                         m_jni_info->m_class_Character,
1975                                         m_jni_info->m_ctor_Character_with_char,
1976                                         &arg ) );
1977                                 jni.ensure_no_exception();
1978                                 jni->SetObjectField(
1979                                     jo_comp.get(), field_id, jo.get() );
1980                             } else {
1981                                 jni->SetCharField(
1982                                     jo_comp.get(),
1983                                     field_id, *(jchar const *) p );
1984                             }
1985                             break;
1986                         case typelib_TypeClass_BOOLEAN:
1987                             if (parameterizedType) {
1988                                 jvalue arg;
1989                                 arg.z = *(jboolean const *) p;
1990                                 JLocalAutoRef jo(
1991                                     jni,
1992                                     jni->NewObjectA(
1993                                         m_jni_info->m_class_Boolean,
1994                                         m_jni_info->m_ctor_Boolean_with_boolean,
1995                                         &arg ) );
1996                                 jni.ensure_no_exception();
1997                                 jni->SetObjectField(
1998                                     jo_comp.get(), field_id, jo.get() );
1999                             } else {
2000                                 jni->SetBooleanField(
2001                                     jo_comp.get(),
2002                                     field_id, *(jboolean const *) p );
2003                             }
2004                             break;
2005                         case typelib_TypeClass_BYTE:
2006                             if (parameterizedType) {
2007                                 jvalue arg;
2008                                 arg.b = *(jbyte const *) p;
2009                                 JLocalAutoRef jo(
2010                                     jni,
2011                                     jni->NewObjectA(
2012                                         m_jni_info->m_class_Byte,
2013                                         m_jni_info->m_ctor_Byte_with_byte,
2014                                         &arg ) );
2015                                 jni.ensure_no_exception();
2016                                 jni->SetObjectField(
2017                                     jo_comp.get(), field_id, jo.get() );
2018                             } else {
2019                                 jni->SetByteField(
2020                                     jo_comp.get(),
2021                                     field_id, *(jbyte const *) p );
2022                             }
2023                             break;
2024                         case typelib_TypeClass_SHORT:
2025                         case typelib_TypeClass_UNSIGNED_SHORT:
2026                             if (parameterizedType) {
2027                                 jvalue arg;
2028                                 arg.s = *(jshort const *) p;
2029                                 JLocalAutoRef jo(
2030                                     jni,
2031                                     jni->NewObjectA(
2032                                         m_jni_info->m_class_Short,
2033                                         m_jni_info->m_ctor_Short_with_short,
2034                                         &arg ) );
2035                                 jni.ensure_no_exception();
2036                                 jni->SetObjectField(
2037                                     jo_comp.get(), field_id, jo.get() );
2038                             } else {
2039                                 jni->SetShortField(
2040                                     jo_comp.get(),
2041                                     field_id, *(jshort const *) p );
2042                             }
2043                             break;
2044                         case typelib_TypeClass_LONG:
2045                         case typelib_TypeClass_UNSIGNED_LONG:
2046                             if (parameterizedType) {
2047                                 jvalue arg;
2048                                 arg.i = *(jint const *) p;
2049                                 JLocalAutoRef jo(
2050                                     jni,
2051                                     jni->NewObjectA(
2052                                         m_jni_info->m_class_Integer,
2053                                         m_jni_info->m_ctor_Integer_with_int,
2054                                         &arg ) );
2055                                 jni.ensure_no_exception();
2056                                 jni->SetObjectField(
2057                                     jo_comp.get(), field_id, jo.get() );
2058                             } else {
2059                                 jni->SetIntField(
2060                                     jo_comp.get(),
2061                                     field_id, *(jint const *) p );
2062                             }
2063                             break;
2064                         case typelib_TypeClass_HYPER:
2065                         case typelib_TypeClass_UNSIGNED_HYPER:
2066                             if (parameterizedType) {
2067                                 jvalue arg;
2068                                 arg.j = *(jlong const *) p;
2069                                 JLocalAutoRef jo(
2070                                     jni,
2071                                     jni->NewObjectA(
2072                                         m_jni_info->m_class_Long,
2073                                         m_jni_info->m_ctor_Long_with_long,
2074                                         &arg ) );
2075                                 jni.ensure_no_exception();
2076                                 jni->SetObjectField(
2077                                     jo_comp.get(), field_id, jo.get() );
2078                             } else {
2079                                 jni->SetLongField(
2080                                     jo_comp.get(),
2081                                     field_id, *(jlong const *) p );
2082                             }
2083                             break;
2084                         case typelib_TypeClass_FLOAT:
2085                             if (parameterizedType) {
2086                                 jvalue arg;
2087                                 arg.f = *(jfloat const *) p;
2088                                 JLocalAutoRef jo(
2089                                     jni,
2090                                     jni->NewObjectA(
2091                                         m_jni_info->m_class_Float,
2092                                         m_jni_info->m_ctor_Float_with_float,
2093                                         &arg ) );
2094                                 jni.ensure_no_exception();
2095                                 jni->SetObjectField(
2096                                     jo_comp.get(), field_id, jo.get() );
2097                             } else {
2098                                 jni->SetFloatField(
2099                                     jo_comp.get(),
2100                                     field_id, *(jfloat const *) p );
2101                             }
2102                             break;
2103                         case typelib_TypeClass_DOUBLE:
2104                             if (parameterizedType) {
2105                                 jvalue arg;
2106                                 arg.d = *(jdouble const *) p;
2107                                 JLocalAutoRef jo(
2108                                     jni,
2109                                     jni->NewObjectA(
2110                                         m_jni_info->m_class_Double,
2111                                         m_jni_info->m_ctor_Double_with_double,
2112                                         &arg ) );
2113                                 jni.ensure_no_exception();
2114                                 jni->SetObjectField(
2115                                     jo_comp.get(), field_id, jo.get() );
2116                             } else {
2117                                 jni->SetDoubleField(
2118                                     jo_comp.get(),
2119                                     field_id, *(jdouble const *) p );
2120                             }
2121                             break;
2122                         case typelib_TypeClass_STRING: // string opt here
2123                         {
2124                             JLocalAutoRef jo_string(
2125                                 jni, ustring_to_jstring(
2126                                     jni, *(rtl_uString * const *) p ) );
2127                             jni->SetObjectField(
2128                                 jo_comp.get(), field_id, jo_string.get() );
2129                             break;
2130                         }
2131                         default:
2132                         {
2133                             jvalue java_data2;
2134                             map_to_java(
2135                                 jni, &java_data2, p, member_type, 0,
2136                                 true /* in */, false /* no out */ );
2137                             JLocalAutoRef jo_obj( jni, java_data2.l );
2138                             jni->SetObjectField(
2139                                 jo_comp.get(), field_id, jo_obj.get() );
2140                             break;
2141                         }
2142                         }
2143                     }
2144                 }
2145             }
2146         }
2147         if (out_param)
2148         {
2149             if (0 == java_data->l)
2150             {
2151                 java_data->l =
2152                     jni->NewObjectArray( 1, comp_info->m_class, jo_comp.get() );
2153                 jni.ensure_no_exception();
2154             }
2155             else
2156             {
2157                 jni->SetObjectArrayElement(
2158                     (jobjectArray) java_data->l, 0, jo_comp.get() );
2159                 jni.ensure_no_exception();
2160             }
2161         }
2162         else
2163         {
2164             java_data->l = jo_comp.release();
2165         }
2166         break;
2167     }
2168     case typelib_TypeClass_SEQUENCE:
2169     {
2170         // xxx todo: possible opt for pure out sequences
2171         JLocalAutoRef jo_ar( jni );
2172 
2173         sal_Int32 nElements;
2174         uno_Sequence const * seq = 0;
2175         if (in_param)
2176         {
2177             seq = *(uno_Sequence * const *)uno_data;
2178             nElements = seq->nElements;
2179         }
2180         else
2181         {
2182             nElements = 0;
2183         }
2184 
2185         TypeDescr td( type );
2186         typelib_TypeDescriptionReference * element_type =
2187             ((typelib_IndirectTypeDescription *)td.get())->pType;
2188 
2189         switch (element_type->eTypeClass)
2190         {
2191         case typelib_TypeClass_CHAR:
2192             jo_ar.reset( jni->NewCharArray( nElements ) );
2193             jni.ensure_no_exception();
2194             if (0 < nElements)
2195             {
2196                 jni->SetCharArrayRegion(
2197                     (jcharArray) jo_ar.get(),
2198                     0, nElements, (jchar *) seq->elements );
2199                 jni.ensure_no_exception();
2200             }
2201             break;
2202         case typelib_TypeClass_BOOLEAN:
2203             jo_ar.reset( jni->NewBooleanArray( nElements ) );
2204             jni.ensure_no_exception();
2205             if (0 < nElements)
2206             {
2207                 jni->SetBooleanArrayRegion(
2208                     (jbooleanArray) jo_ar.get(),
2209                     0, nElements, (jboolean *) seq->elements );
2210                 jni.ensure_no_exception();
2211             }
2212             break;
2213         case typelib_TypeClass_BYTE:
2214             jo_ar.reset( jni->NewByteArray( nElements ) );
2215             jni.ensure_no_exception();
2216             if (0 < nElements)
2217             {
2218                 jni->SetByteArrayRegion(
2219                     (jbyteArray) jo_ar.get(),
2220                     0, nElements, (jbyte *) seq->elements );
2221                 jni.ensure_no_exception();
2222             }
2223             break;
2224         case typelib_TypeClass_SHORT:
2225         case typelib_TypeClass_UNSIGNED_SHORT:
2226             jo_ar.reset( jni->NewShortArray( nElements ) );
2227             jni.ensure_no_exception();
2228             if (0 < nElements)
2229             {
2230                 jni->SetShortArrayRegion(
2231                     (jshortArray) jo_ar.get(),
2232                     0, nElements, (jshort *) seq->elements );
2233                 jni.ensure_no_exception();
2234             }
2235             break;
2236         case typelib_TypeClass_LONG:
2237         case typelib_TypeClass_UNSIGNED_LONG:
2238             jo_ar.reset( jni->NewIntArray( nElements ) );
2239             jni.ensure_no_exception();
2240             if (0 < nElements)
2241             {
2242                 jni->SetIntArrayRegion(
2243                     (jintArray) jo_ar.get(),
2244                     0, nElements, (jint *) seq->elements );
2245                 jni.ensure_no_exception();
2246             }
2247             break;
2248         case typelib_TypeClass_HYPER:
2249         case typelib_TypeClass_UNSIGNED_HYPER:
2250             jo_ar.reset( jni->NewLongArray( nElements ) );
2251             jni.ensure_no_exception();
2252             if (0 < nElements)
2253             {
2254                 jni->SetLongArrayRegion(
2255                     (jlongArray) jo_ar.get(),
2256                     0, nElements, (jlong *) seq->elements );
2257                 jni.ensure_no_exception();
2258             }
2259             break;
2260         case typelib_TypeClass_FLOAT:
2261             jo_ar.reset( jni->NewFloatArray( nElements ) );
2262             jni.ensure_no_exception();
2263             if (0 < nElements)
2264             {
2265                 jni->SetFloatArrayRegion(
2266                     (jfloatArray) jo_ar.get(),
2267                     0, nElements, (jfloat *) seq->elements );
2268                 jni.ensure_no_exception();
2269             }
2270             break;
2271         case typelib_TypeClass_DOUBLE:
2272             jo_ar.reset( jni->NewDoubleArray( nElements ) );
2273             jni.ensure_no_exception();
2274             if (0 < nElements)
2275             {
2276                 jni->SetDoubleArrayRegion(
2277                     (jdoubleArray) jo_ar.get(),
2278                     0, nElements, (jdouble *) seq->elements );
2279                 jni.ensure_no_exception();
2280             }
2281             break;
2282         case typelib_TypeClass_STRING:
2283             jo_ar.reset(
2284                 jni->NewObjectArray(
2285                     nElements, m_jni_info->m_class_String, 0 ) );
2286             jni.ensure_no_exception();
2287             if (in_param)
2288             {
2289                 rtl_uString * const * pp =
2290                     (rtl_uString * const *) seq->elements;
2291                 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2292                 {
2293                     JLocalAutoRef jo_string(
2294                         jni, ustring_to_jstring( jni, pp[ nPos ] ) );
2295                     jni->SetObjectArrayElement(
2296                         (jobjectArray) jo_ar.get(), nPos, jo_string.get() );
2297                     jni.ensure_no_exception();
2298                 }
2299             }
2300             break;
2301         case typelib_TypeClass_TYPE:
2302             jo_ar.reset(
2303                 jni->NewObjectArray( nElements, m_jni_info->m_class_Type, 0 ) );
2304             jni.ensure_no_exception();
2305             if (in_param)
2306             {
2307                 typelib_TypeDescriptionReference * const * pp =
2308                     (typelib_TypeDescriptionReference * const *)seq->elements;
2309                 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2310                 {
2311                     jvalue val;
2312                     map_to_java(
2313                         jni, &val, &pp[ nPos ], element_type, 0,
2314                         true /* in */, false /* no out */ );
2315                     JLocalAutoRef jo_element( jni, val.l );
2316                     jni->SetObjectArrayElement(
2317                         (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
2318                     jni.ensure_no_exception();
2319                 }
2320             }
2321             break;
2322         case typelib_TypeClass_ANY:
2323             jo_ar.reset(
2324                 jni->NewObjectArray(
2325                     nElements, m_jni_info->m_class_Object, 0 ) );
2326             jni.ensure_no_exception();
2327             if (in_param)
2328             {
2329                 uno_Any const * p = (uno_Any const *)seq->elements;
2330                 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2331                 {
2332                     jvalue val;
2333                     map_to_java(
2334                         jni, &val, &p[ nPos ], element_type, 0,
2335                         true /* in */, false /* no out */ );
2336                     JLocalAutoRef jo_element( jni, val.l );
2337                     jni->SetObjectArrayElement(
2338                         (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
2339                     jni.ensure_no_exception();
2340                 }
2341             }
2342             break;
2343         case typelib_TypeClass_ENUM:
2344         {
2345             OUString const & element_type_name =
2346                 OUString::unacquired( &element_type->pTypeName );
2347             OString class_name(
2348                 OUStringToOString(
2349                     element_type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
2350             JLocalAutoRef jo_enum_class(
2351                 jni, find_class( jni, class_name.getStr() ) );
2352 
2353             jo_ar.reset(
2354                 jni->NewObjectArray(
2355                     nElements, (jclass) jo_enum_class.get(), 0 ) );
2356             jni.ensure_no_exception();
2357 
2358             if (0 < nElements)
2359             {
2360                 // call static <enum_class>.fromInt( int )
2361                 OStringBuffer sig_buf( 5 + class_name.getLength() );
2362                 sig_buf.append( RTL_CONSTASCII_STRINGPARAM("(I)L") );
2363                 sig_buf.append( class_name.replace( '.', '/' ) );
2364                 sig_buf.append( ';' );
2365                 OString sig( sig_buf.makeStringAndClear() );
2366                 jmethodID method_id = jni->GetStaticMethodID(
2367                     (jclass) jo_enum_class.get(), "fromInt", sig.getStr() );
2368                 jni.ensure_no_exception();
2369                 OSL_ASSERT( 0 != method_id );
2370 
2371                 sal_Int32 const * p = (sal_Int32 const *)seq->elements;
2372                 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2373                 {
2374                     jvalue arg;
2375                     arg.i = p[ nPos ];
2376                     JLocalAutoRef jo_enum(
2377                         jni, jni->CallStaticObjectMethodA(
2378                             (jclass) jo_enum_class.get(), method_id, &arg ) );
2379                     jni.ensure_no_exception();
2380                     jni->SetObjectArrayElement(
2381                         (jobjectArray) jo_ar.get(), nPos, jo_enum.get() );
2382                     jni.ensure_no_exception();
2383                 }
2384             }
2385             break;
2386         }
2387         case typelib_TypeClass_STRUCT:
2388         case typelib_TypeClass_EXCEPTION:
2389         {
2390             JNI_type_info const * element_info =
2391                 m_jni_info->get_type_info( jni, element_type );
2392 
2393             jo_ar.reset(
2394                 jni->NewObjectArray( nElements, element_info->m_class, 0 ) );
2395             jni.ensure_no_exception();
2396 
2397             if (0 < nElements)
2398             {
2399                 char * p = (char *)seq->elements;
2400                 sal_Int32 nSize = element_info->m_td.get()->nSize;
2401                 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2402                 {
2403                     jvalue val;
2404                     map_to_java(
2405                         jni, &val, p + (nSize * nPos),
2406                         element_type, element_info,
2407                         true /* in */, false /* no out */ );
2408                     JLocalAutoRef jo_element( jni, val.l );
2409                     jni->SetObjectArrayElement(
2410                         (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
2411                     jni.ensure_no_exception();
2412                 }
2413             }
2414             break;
2415         }
2416         case typelib_TypeClass_SEQUENCE:
2417         {
2418             OStringBuffer buf( 64 );
2419             JNI_info::append_sig(
2420                 &buf, element_type, false /* use class XInterface */,
2421                 false /* '.' instead of '/' */ );
2422             OString class_name( buf.makeStringAndClear() );
2423             JLocalAutoRef jo_seq_class(
2424                 jni, find_class( jni, class_name.getStr() ) );
2425 
2426             jo_ar.reset(
2427                 jni->NewObjectArray(
2428                     nElements, (jclass) jo_seq_class.get(), 0 ) );
2429             jni.ensure_no_exception();
2430 
2431             if (0 < nElements)
2432             {
2433                 TypeDescr element_td( element_type );
2434                 uno_Sequence ** elements = (uno_Sequence **) seq->elements;
2435                 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2436                 {
2437                     jvalue java_data2;
2438                     map_to_java(
2439                         jni, &java_data2, elements + nPos, element_type, 0,
2440                         true /* in */, false /* no out */ );
2441                     JLocalAutoRef jo_seq( jni, java_data2.l );
2442                     jni->SetObjectArrayElement(
2443                         (jobjectArray) jo_ar.get(), nPos, jo_seq.get() );
2444                     jni.ensure_no_exception();
2445                 }
2446             }
2447             break;
2448         }
2449         case typelib_TypeClass_INTERFACE:
2450         {
2451             JNI_interface_type_info const * iface_info =
2452                 static_cast< JNI_interface_type_info const * >(
2453                     m_jni_info->get_type_info( jni, element_type ) );
2454 
2455             jo_ar.reset(
2456                 jni->NewObjectArray( nElements, iface_info->m_class, 0 ) );
2457             jni.ensure_no_exception();
2458 
2459             if (0 < nElements)
2460             {
2461                 uno_Interface ** pp = (uno_Interface **)seq->elements;
2462                 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2463                 {
2464                     uno_Interface * pUnoI = pp[ nPos ];
2465                     if (0 != pUnoI)
2466                     {
2467                         JLocalAutoRef jo_element(
2468                             jni, map_to_java( jni, pUnoI, iface_info ) );
2469                         jni->SetObjectArrayElement(
2470                             (jobjectArray) jo_ar.get(),
2471                             nPos, jo_element.get() );
2472                         jni.ensure_no_exception();
2473                     }
2474                 }
2475             }
2476             break;
2477         }
2478         default:
2479         {
2480             OUStringBuffer buf( 128 );
2481             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_java():") );
2482             buf.append( OUString::unacquired( &type->pTypeName ) );
2483             buf.appendAscii(
2484                 RTL_CONSTASCII_STRINGPARAM("] unsupported element type: ") );
2485             buf.append( OUString::unacquired( &element_type->pTypeName ) );
2486             buf.append( jni.get_stack_trace() );
2487             throw BridgeRuntimeError( buf.makeStringAndClear() );
2488         }
2489         }
2490 
2491         if (out_param)
2492         {
2493             if (0 == java_data->l)
2494             {
2495                 JLocalAutoRef jo_element_class(
2496                     jni, jni->GetObjectClass( jo_ar.get() ) );
2497                 if (in_param)
2498                 {
2499                     java_data->l = jni->NewObjectArray(
2500                         1, (jclass) jo_element_class.get(), jo_ar.get() );
2501                 }
2502                 else
2503                 {
2504                     java_data->l = jni->NewObjectArray(
2505                         1, (jclass) jo_element_class.get(), 0 );
2506                 }
2507                 jni.ensure_no_exception();
2508             }
2509             else
2510             {
2511                 jni->SetObjectArrayElement(
2512                     (jobjectArray) java_data->l, 0, jo_ar.get() );
2513                 jni.ensure_no_exception();
2514             }
2515         }
2516         else
2517         {
2518             java_data->l = jo_ar.release();
2519         }
2520         break;
2521     }
2522     case typelib_TypeClass_INTERFACE:
2523     {
2524         JLocalAutoRef jo_iface( jni );
2525         if (in_param)
2526         {
2527             uno_Interface * pUnoI = *(uno_Interface * const *)uno_data;
2528             if (0 != pUnoI)
2529             {
2530                 if (0 == info)
2531                     info = m_jni_info->get_type_info( jni, type );
2532                 JNI_interface_type_info const * iface_info =
2533                     static_cast< JNI_interface_type_info const * >( info );
2534                 jo_iface.reset( map_to_java( jni, pUnoI, iface_info ) );
2535             }
2536         }
2537         if (out_param)
2538         {
2539             if (0 == java_data->l)
2540             {
2541                 if (0 == info)
2542                     info = m_jni_info->get_type_info( jni, type );
2543                 java_data->l =
2544                     jni->NewObjectArray( 1, info->m_class, jo_iface.get() );
2545                 jni.ensure_no_exception();
2546             }
2547             else
2548             {
2549                 jni->SetObjectArrayElement(
2550                     (jobjectArray) java_data->l, 0, jo_iface.get() );
2551                 jni.ensure_no_exception();
2552             }
2553         }
2554         else
2555         {
2556             java_data->l = jo_iface.release();
2557         }
2558         break;
2559     }
2560     default:
2561     {
2562         OUStringBuffer buf( 128 );
2563         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_java():") );
2564         buf.append( OUString::unacquired( &type->pTypeName ) );
2565         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
2566         buf.append( jni.get_stack_trace() );
2567         throw BridgeRuntimeError( buf.makeStringAndClear() );
2568     }
2569     }
2570 }
2571 
2572 }
2573