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