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