bump product version to 5.0.4.1
[LibreOffice.git] / bridges / source / jni_uno / jni_data.cxx
blob3e3ed84b3aa4bc395b2c13a08974f321229665fb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <cassert>
23 #include <memory>
25 #include "jni_bridge.h"
27 #include "rtl/strbuf.hxx"
28 #include "uno/sequence2.h"
30 namespace jni_uno
34 inline rtl_mem * seq_allocate( sal_Int32 nElements, sal_Int32 nSize )
36 std::unique_ptr< rtl_mem > seq(
37 rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
38 uno_Sequence * p = reinterpret_cast<uno_Sequence *>(seq.get());
39 p->nRefCount = 1;
40 p->nElements = nElements;
41 return seq.release();
45 namespace {
47 void createDefaultUnoValue(
48 JNI_context const & jni, void * uno_data,
49 typelib_TypeDescriptionReference * type,
50 JNI_type_info const * info /* maybe 0 */, bool assign)
52 switch (type->eTypeClass) {
53 case typelib_TypeClass_BOOLEAN:
54 *static_cast< sal_Bool * >(uno_data) = false;
55 break;
57 case typelib_TypeClass_BYTE:
58 *static_cast< sal_Int8 * >(uno_data) = 0;
59 break;
61 case typelib_TypeClass_SHORT:
62 *static_cast< sal_Int16 * >(uno_data) = 0;
63 break;
65 case typelib_TypeClass_UNSIGNED_SHORT:
66 *static_cast< sal_uInt16 * >(uno_data) = 0;
67 break;
69 case typelib_TypeClass_LONG:
70 *static_cast< sal_Int32 * >(uno_data) = 0;
71 break;
73 case typelib_TypeClass_UNSIGNED_LONG:
74 *static_cast< sal_uInt32 * >(uno_data) = 0;
75 break;
77 case typelib_TypeClass_HYPER:
78 *static_cast< sal_Int64 * >(uno_data) = 0;
79 break;
81 case typelib_TypeClass_UNSIGNED_HYPER:
82 *static_cast< sal_uInt64 * >(uno_data) = 0;
83 break;
85 case typelib_TypeClass_FLOAT:
86 *static_cast< float * >(uno_data) = 0;
87 break;
89 case typelib_TypeClass_DOUBLE:
90 *static_cast< double * >(uno_data) = 0;
91 break;
93 case typelib_TypeClass_CHAR:
94 *static_cast< sal_Unicode * >(uno_data) = 0;
95 break;
97 case typelib_TypeClass_STRING:
98 if (!assign) {
99 *static_cast< rtl_uString ** >(uno_data) = 0;
101 rtl_uString_new(static_cast< rtl_uString ** >(uno_data));
102 break;
104 case typelib_TypeClass_TYPE:
105 if (assign) {
106 typelib_typedescriptionreference_release(
107 *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
109 *static_cast< typelib_TypeDescriptionReference ** >(uno_data)
110 = *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
111 assert(
112 *static_cast< typelib_TypeDescriptionReference ** >(uno_data) != 0);
113 typelib_typedescriptionreference_acquire(
114 *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
115 break;
117 case typelib_TypeClass_ANY:
118 if (assign) {
119 uno_any_destruct(static_cast< uno_Any * >(uno_data), 0);
121 uno_any_construct(
122 static_cast< uno_Any * >(uno_data), 0,
123 jni.get_info()->m_XInterface_type_info->m_td.get(), 0);
124 break;
126 case typelib_TypeClass_SEQUENCE:
128 std::unique_ptr< rtl_mem > seq(seq_allocate(0, 0));
129 if (assign) {
130 uno_type_destructData(uno_data, type, 0);
132 *static_cast< uno_Sequence ** >(uno_data)
133 = reinterpret_cast< uno_Sequence * >(seq.release());
134 break;
137 case typelib_TypeClass_ENUM:
139 typelib_TypeDescription * td = 0;
140 TYPELIB_DANGER_GET(&td, type);
141 *static_cast< sal_Int32 * >(uno_data)
142 = (reinterpret_cast< typelib_EnumTypeDescription * >(td)->
143 nDefaultEnumValue);
144 TYPELIB_DANGER_RELEASE(td);
145 break;
148 case typelib_TypeClass_STRUCT:
150 if (info == 0) {
151 info = jni.get_info()->get_type_info(jni, type);
153 JNI_compound_type_info const * comp_info
154 = static_cast< JNI_compound_type_info const * >(info);
155 typelib_CompoundTypeDescription * comp_td
156 = reinterpret_cast< typelib_CompoundTypeDescription * >(
157 comp_info->m_td.get());
158 sal_Int32 nPos = 0;
159 sal_Int32 nMembers = comp_td->nMembers;
160 try {
161 if (comp_td->pBaseTypeDescription != 0) {
162 createDefaultUnoValue(
163 jni, uno_data,
164 comp_td->pBaseTypeDescription->aBase.pWeakRef,
165 comp_info->m_base, assign);
167 for (; nPos < nMembers; ++nPos) {
168 createDefaultUnoValue(
169 jni,
170 (static_cast< char * >(uno_data)
171 + comp_td->pMemberOffsets[nPos]),
172 comp_td->ppTypeRefs[nPos], 0, assign);
174 } catch (...) {
175 if (!assign) {
176 for (sal_Int32 i = 0; i < nPos; ++i) {
177 uno_type_destructData(
178 (static_cast< char * >(uno_data)
179 + comp_td->pMemberOffsets[i]),
180 comp_td->ppTypeRefs[i], 0);
182 if (comp_td->pBaseTypeDescription != 0) {
183 uno_destructData(
184 uno_data, &comp_td->pBaseTypeDescription->aBase, 0);
187 throw;
190 break;
192 case typelib_TypeClass_INTERFACE:
193 if (assign) {
194 uno_Interface * p = *static_cast< uno_Interface ** >(uno_data);
195 if (p != 0) {
196 (*p->release)(p);
199 *static_cast< uno_Interface ** >(uno_data) = 0;
200 break;
202 default:
203 assert(false);
204 break;
210 void Bridge::map_to_uno(
211 JNI_context const & jni,
212 void * uno_data, jvalue java_data,
213 typelib_TypeDescriptionReference * type,
214 JNI_type_info const * info /* maybe 0 */,
215 bool assign, bool out_param,
216 bool special_wrapped_integral_types ) const
218 assert(
219 !out_param ||
220 (1 == jni->GetArrayLength( static_cast<jarray>(java_data.l) )) );
222 switch (type->eTypeClass)
224 case typelib_TypeClass_CHAR:
225 if (out_param)
227 jni->GetCharArrayRegion(
228 static_cast<jcharArray>(java_data.l), 0, 1, static_cast<jchar *>(uno_data) );
229 jni.ensure_no_exception();
231 else if (special_wrapped_integral_types)
233 *static_cast<jchar *>(uno_data) = jni->CallCharMethodA(
234 java_data.l, getJniInfo()->m_method_Character_charValue, 0 );
235 jni.ensure_no_exception();
237 else
239 *static_cast<jchar *>(uno_data) = java_data.c;
241 break;
242 case typelib_TypeClass_BOOLEAN:
243 if (out_param)
245 jni->GetBooleanArrayRegion(
246 static_cast<jbooleanArray>(java_data.l), 0, 1, static_cast<jboolean *>(uno_data) );
247 jni.ensure_no_exception();
249 else if (special_wrapped_integral_types)
251 *static_cast<jboolean *>(uno_data) = jni->CallBooleanMethodA(
252 java_data.l, getJniInfo()->m_method_Boolean_booleanValue, 0 );
253 jni.ensure_no_exception();
255 else
257 *static_cast<jboolean *>(uno_data) = java_data.z;
259 break;
260 case typelib_TypeClass_BYTE:
261 if (out_param)
263 jni->GetByteArrayRegion(
264 static_cast<jbyteArray>(java_data.l), 0, 1, static_cast<jbyte *>(uno_data) );
265 jni.ensure_no_exception();
267 else if (special_wrapped_integral_types)
269 *static_cast<jbyte *>(uno_data) = jni->CallByteMethodA(
270 java_data.l, getJniInfo()->m_method_Byte_byteValue, 0 );
271 jni.ensure_no_exception();
273 else
275 *static_cast<jbyte *>(uno_data) = java_data.b;
277 break;
278 case typelib_TypeClass_SHORT:
279 case typelib_TypeClass_UNSIGNED_SHORT:
280 if (out_param)
282 jni->GetShortArrayRegion(
283 static_cast<jshortArray>(java_data.l), 0, 1, static_cast<jshort *>(uno_data) );
284 jni.ensure_no_exception();
286 else if (special_wrapped_integral_types)
288 *static_cast<jshort *>(uno_data) = jni->CallShortMethodA(
289 java_data.l, getJniInfo()->m_method_Short_shortValue, 0 );
290 jni.ensure_no_exception();
292 else
294 *static_cast<jshort *>(uno_data) = java_data.s;
296 break;
297 case typelib_TypeClass_LONG:
298 case typelib_TypeClass_UNSIGNED_LONG:
299 if (out_param)
301 jni->GetIntArrayRegion(
302 static_cast<jintArray>(java_data.l), 0, 1, static_cast<jint *>(uno_data) );
303 jni.ensure_no_exception();
305 else if (special_wrapped_integral_types)
307 *static_cast<jint *>(uno_data) = jni->CallIntMethodA(
308 java_data.l, getJniInfo()->m_method_Integer_intValue, 0 );
309 jni.ensure_no_exception();
311 else
313 *static_cast<jint *>(uno_data) = java_data.i;
315 break;
316 case typelib_TypeClass_HYPER:
317 case typelib_TypeClass_UNSIGNED_HYPER:
318 if (out_param)
320 jni->GetLongArrayRegion(
321 static_cast<jlongArray>(java_data.l), 0, 1, static_cast<jlong *>(uno_data) );
322 jni.ensure_no_exception();
324 else if (special_wrapped_integral_types)
326 *static_cast<jlong *>(uno_data) = jni->CallLongMethodA(
327 java_data.l, getJniInfo()->m_method_Long_longValue, 0 );
328 jni.ensure_no_exception();
330 else
332 *static_cast<jlong *>(uno_data) = java_data.j;
334 break;
335 case typelib_TypeClass_FLOAT:
336 if (out_param)
338 jni->GetFloatArrayRegion(
339 static_cast<jfloatArray>(java_data.l), 0, 1, static_cast<jfloat *>(uno_data) );
340 jni.ensure_no_exception();
342 else if (special_wrapped_integral_types)
344 *static_cast<jfloat *>(uno_data) = jni->CallFloatMethodA(
345 java_data.l, getJniInfo()->m_method_Float_floatValue, 0 );
346 jni.ensure_no_exception();
348 else
350 *static_cast<jfloat *>(uno_data) = java_data.f;
352 break;
353 case typelib_TypeClass_DOUBLE:
354 if (out_param)
356 jni->GetDoubleArrayRegion(
357 static_cast<jdoubleArray>(java_data.l), 0, 1, static_cast<jdouble *>(uno_data) );
358 jni.ensure_no_exception();
360 else if (special_wrapped_integral_types)
362 *static_cast<jdouble *>(uno_data) = jni->CallDoubleMethodA(
363 java_data.l, getJniInfo()->m_method_Double_doubleValue, 0 );
364 jni.ensure_no_exception();
366 else
368 *static_cast<jdouble *>(uno_data) = java_data.d;
370 break;
371 case typelib_TypeClass_STRING:
373 JLocalAutoRef jo_out_holder( jni );
374 if (out_param)
376 jo_out_holder.reset(
377 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
378 jni.ensure_no_exception();
379 java_data.l = jo_out_holder.get();
381 if (0 == java_data.l)
383 throw BridgeRuntimeError(
384 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
385 + "] null-ref given!" + jni.get_stack_trace() );
387 if (! assign)
388 *static_cast<rtl_uString **>(uno_data) = 0;
389 jstring_to_ustring(
390 jni, static_cast<rtl_uString **>(uno_data), static_cast<jstring>(java_data.l) );
391 break;
393 case typelib_TypeClass_TYPE:
395 JLocalAutoRef jo_out_holder( jni );
396 if (out_param)
398 jo_out_holder.reset(
399 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
400 jni.ensure_no_exception();
401 java_data.l = jo_out_holder.get();
403 if (0 == java_data.l)
405 throw BridgeRuntimeError(
406 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
407 + "] null-ref given!" + jni.get_stack_trace() );
410 // type name
411 JLocalAutoRef jo_type_name(
412 jni, jni->GetObjectField(
413 java_data.l, getJniInfo()->m_field_Type__typeName ) );
414 if (! jo_type_name.is())
416 throw BridgeRuntimeError(
417 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
418 + "] incomplete type object: no type name!"
419 + jni.get_stack_trace() );
421 OUString type_name(
422 jstring_to_oustring( jni, static_cast<jstring>(jo_type_name.get()) ) );
423 ::com::sun::star::uno::TypeDescription td( type_name );
424 if (! td.is())
426 throw BridgeRuntimeError(
427 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
428 + "] UNO type not found: " + type_name
429 + jni.get_stack_trace() );
431 typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
432 if (assign)
434 typelib_typedescriptionreference_release(
435 *static_cast<typelib_TypeDescriptionReference **>(uno_data) );
437 *static_cast<typelib_TypeDescriptionReference **>(uno_data) = td.get()->pWeakRef;
438 break;
440 case typelib_TypeClass_ANY:
442 JLocalAutoRef jo_out_holder( jni );
443 if (out_param)
445 jo_out_holder.reset(
446 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
447 jni.ensure_no_exception();
448 java_data.l = jo_out_holder.get();
451 uno_Any * pAny = static_cast<uno_Any *>(uno_data);
452 if (0 == java_data.l) // null-ref maps to XInterface null-ref
454 if (assign)
455 uno_any_destruct( pAny, 0 );
456 uno_any_construct(
457 pAny, 0, getJniInfo()->m_XInterface_type_info->m_td.get(), 0 );
458 break;
461 JLocalAutoRef jo_type( jni );
462 JLocalAutoRef jo_wrapped_holder( jni );
464 if (jni->IsInstanceOf( java_data.l, getJniInfo()->m_class_Any ))
466 // boxed any
467 jo_type.reset( jni->GetObjectField(
468 java_data.l, getJniInfo()->m_field_Any__type ) );
469 if (! jo_type.is())
471 throw BridgeRuntimeError(
472 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
473 + "] no type set at com.sun.star.uno.Any!"
474 + jni.get_stack_trace() );
476 // wrapped value
477 jo_wrapped_holder.reset(
478 jni->GetObjectField(
479 java_data.l, getJniInfo()->m_field_Any__object ) );
480 java_data.l = jo_wrapped_holder.get();
482 else
484 // create type out of class
485 JLocalAutoRef jo_class( jni, jni->GetObjectClass( java_data.l ) );
486 jo_type.reset( create_type( jni, static_cast<jclass>(jo_class.get()) ) );
489 // get type name
490 JLocalAutoRef jo_type_name(
491 jni, jni->GetObjectField(
492 jo_type.get(), getJniInfo()->m_field_Type__typeName ) );
493 jni.ensure_no_exception();
494 OUString type_name(
495 jstring_to_oustring( jni, static_cast<jstring>(jo_type_name.get()) ) );
497 ::com::sun::star::uno::TypeDescription value_td( type_name );
498 if (! value_td.is())
500 throw BridgeRuntimeError(
501 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
502 + "] UNO type not found: " + type_name
503 + jni.get_stack_trace() );
505 typelib_TypeClass type_class = value_td.get()->eTypeClass;
507 if (assign)
509 uno_any_destruct( pAny, 0 );
513 switch (type_class)
515 case typelib_TypeClass_VOID:
516 pAny->pData = &pAny->pReserved;
517 break;
518 case typelib_TypeClass_CHAR:
519 pAny->pData = &pAny->pReserved;
520 *static_cast<jchar *>(pAny->pData) = jni->CallCharMethodA(
521 java_data.l, getJniInfo()->m_method_Character_charValue, 0 );
522 jni.ensure_no_exception();
523 break;
524 case typelib_TypeClass_BOOLEAN:
525 pAny->pData = &pAny->pReserved;
526 *static_cast<jboolean *>(pAny->pData) = jni->CallBooleanMethodA(
527 java_data.l, getJniInfo()->m_method_Boolean_booleanValue, 0 );
528 jni.ensure_no_exception();
529 break;
530 case typelib_TypeClass_BYTE:
531 pAny->pData = &pAny->pReserved;
532 *static_cast<jbyte *>(pAny->pData) = jni->CallByteMethodA(
533 java_data.l, getJniInfo()->m_method_Byte_byteValue, 0 );
534 jni.ensure_no_exception();
535 break;
536 case typelib_TypeClass_SHORT:
537 case typelib_TypeClass_UNSIGNED_SHORT:
538 pAny->pData = &pAny->pReserved;
539 *static_cast<jshort *>(pAny->pData) = jni->CallShortMethodA(
540 java_data.l, getJniInfo()->m_method_Short_shortValue, 0 );
541 jni.ensure_no_exception();
542 break;
543 case typelib_TypeClass_LONG:
544 case typelib_TypeClass_UNSIGNED_LONG:
545 pAny->pData = &pAny->pReserved;
546 *static_cast<jint *>(pAny->pData) = jni->CallIntMethodA(
547 java_data.l, getJniInfo()->m_method_Integer_intValue, 0 );
548 jni.ensure_no_exception();
549 break;
550 case typelib_TypeClass_HYPER:
551 case typelib_TypeClass_UNSIGNED_HYPER:
552 if (sizeof (sal_Int64) <= sizeof (void *))
554 pAny->pData = &pAny->pReserved;
555 *static_cast<jlong *>(pAny->pData) = jni->CallLongMethodA(
556 java_data.l, getJniInfo()->m_method_Long_longValue, 0 );
557 jni.ensure_no_exception();
559 else
561 std::unique_ptr< rtl_mem > mem(
562 rtl_mem::allocate( sizeof (sal_Int64) ) );
563 *reinterpret_cast<jlong *>(mem.get()) = jni->CallLongMethodA(
564 java_data.l, getJniInfo()->m_method_Long_longValue, 0 );
565 jni.ensure_no_exception();
566 pAny->pData = mem.release();
568 break;
569 case typelib_TypeClass_FLOAT:
570 if (sizeof (float) <= sizeof (void *))
572 pAny->pData = &pAny->pReserved;
573 *static_cast<jfloat *>(pAny->pData) = jni->CallFloatMethodA(
574 java_data.l, getJniInfo()->m_method_Float_floatValue, 0 );
575 jni.ensure_no_exception();
577 else
579 std::unique_ptr< rtl_mem > mem(
580 rtl_mem::allocate( sizeof (float) ) );
581 *reinterpret_cast<jfloat *>(mem.get()) = jni->CallFloatMethodA(
582 java_data.l, getJniInfo()->m_method_Float_floatValue, 0 );
583 jni.ensure_no_exception();
584 pAny->pData = mem.release();
586 break;
587 case typelib_TypeClass_DOUBLE:
588 if (sizeof (double) <= sizeof (void *))
590 pAny->pData = &pAny->pReserved;
591 *static_cast<jdouble *>(pAny->pData) =
592 jni->CallDoubleMethodA(
593 java_data.l,
594 getJniInfo()->m_method_Double_doubleValue, 0 );
595 jni.ensure_no_exception();
597 else
599 std::unique_ptr< rtl_mem > mem(
600 rtl_mem::allocate( sizeof (double) ) );
601 *reinterpret_cast<jdouble *>(mem.get()) =
602 jni->CallDoubleMethodA(
603 java_data.l,
604 getJniInfo()->m_method_Double_doubleValue, 0 );
605 jni.ensure_no_exception();
606 pAny->pData = mem.release();
608 break;
609 case typelib_TypeClass_STRING:
610 // opt: anies often contain strings; copy string directly
611 pAny->pReserved = 0;
612 pAny->pData = &pAny->pReserved;
613 jstring_to_ustring(
614 jni, static_cast<rtl_uString **>(pAny->pData),
615 static_cast<jstring>(java_data.l) );
616 break;
617 case typelib_TypeClass_TYPE:
618 case typelib_TypeClass_ENUM:
619 case typelib_TypeClass_SEQUENCE:
620 case typelib_TypeClass_INTERFACE:
621 pAny->pData = &pAny->pReserved;
622 map_to_uno(
623 jni, pAny->pData, java_data,
624 value_td.get()->pWeakRef, 0,
625 false /* no assign */, false /* no out param */ );
626 break;
627 case typelib_TypeClass_STRUCT:
628 case typelib_TypeClass_EXCEPTION:
630 std::unique_ptr< rtl_mem > mem(
631 rtl_mem::allocate( value_td.get()->nSize ) );
632 map_to_uno(
633 jni, mem.get(), java_data, value_td.get()->pWeakRef, 0,
634 false /* no assign */, false /* no out param */ );
635 pAny->pData = mem.release();
636 break;
638 default:
640 throw BridgeRuntimeError(
641 "[map_to_uno():" + type_name
642 + "] unsupported value type of any!"
643 + jni.get_stack_trace() );
647 catch (...)
649 if (assign)
651 // restore to valid any
652 uno_any_construct( pAny, 0, 0, 0 );
654 throw;
656 typelib_typedescriptionreference_acquire( value_td.get()->pWeakRef );
657 pAny->pType = value_td.get()->pWeakRef;
658 break;
660 case typelib_TypeClass_ENUM:
662 JLocalAutoRef jo_out_holder( jni );
663 if (out_param)
665 jo_out_holder.reset(
666 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
667 jni.ensure_no_exception();
668 java_data.l = jo_out_holder.get();
670 if (0 == java_data.l)
672 throw BridgeRuntimeError(
673 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
674 + "] null-ref given!" + jni.get_stack_trace() );
677 *static_cast<jint *>(uno_data) = jni->GetIntField(
678 java_data.l, getJniInfo()->m_field_Enum_m_value );
679 break;
681 case typelib_TypeClass_STRUCT:
682 case typelib_TypeClass_EXCEPTION:
684 JLocalAutoRef jo_out_holder( jni );
685 if (out_param)
687 jo_out_holder.reset(
688 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
689 jni.ensure_no_exception();
690 java_data.l = jo_out_holder.get();
692 if (0 == java_data.l)
694 throw BridgeRuntimeError(
695 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
696 + "] null-ref given!" + jni.get_stack_trace() );
699 if (0 == info)
700 info = getJniInfo()->get_type_info( jni, type );
701 JNI_compound_type_info const * comp_info =
702 static_cast< JNI_compound_type_info const * >( info );
704 typelib_CompoundTypeDescription * comp_td =
705 reinterpret_cast<typelib_CompoundTypeDescription *>(comp_info->m_td.get());
706 bool polymorphic
707 = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
708 && reinterpret_cast< typelib_StructTypeDescription * >(
709 comp_td)->pParameterizedTypes != 0;
711 sal_Int32 nPos = 0;
712 sal_Int32 nMembers = comp_td->nMembers;
715 if (0 != comp_td->pBaseTypeDescription)
717 map_to_uno(
718 jni, uno_data, java_data,
719 comp_td->pBaseTypeDescription->aBase.pWeakRef,
720 comp_info->m_base,
721 assign, false /* no out param */ );
724 for ( ; nPos < nMembers; ++nPos )
726 void * p = static_cast<char *>(uno_data) + comp_td->pMemberOffsets[ nPos ];
727 typelib_TypeDescriptionReference * member_type =
728 comp_td->ppTypeRefs[ nPos ];
729 jfieldID field_id = comp_info->m_fields[ nPos ];
730 bool parameterizedType = polymorphic
731 && reinterpret_cast< typelib_StructTypeDescription * >(
732 comp_td)->pParameterizedTypes[nPos];
733 switch (member_type->eTypeClass)
735 case typelib_TypeClass_CHAR:
736 if (parameterizedType) {
737 JLocalAutoRef jo(
738 jni, jni->GetObjectField( java_data.l, field_id ) );
739 if ( jo.get() == 0 ) {
740 *static_cast<jchar *>(p) = 0;
741 } else {
742 jvalue val;
743 val.l = jo.get();
744 map_to_uno(
745 jni, p, val, member_type, 0, assign, false,
746 true );
748 } else {
749 *static_cast<jchar *>(p) = jni->GetCharField(
750 java_data.l, field_id );
752 break;
753 case typelib_TypeClass_BOOLEAN:
754 if (parameterizedType) {
755 JLocalAutoRef jo(
756 jni, jni->GetObjectField( java_data.l, field_id ) );
757 if ( jo.get() == 0 ) {
758 *static_cast<jboolean *>(p) = false;
759 } else {
760 jvalue val;
761 val.l = jo.get();
762 map_to_uno(
763 jni, p, val, member_type, 0, assign, false,
764 true );
766 } else {
767 *static_cast<jboolean *>(p) = jni->GetBooleanField(
768 java_data.l, field_id );
770 break;
771 case typelib_TypeClass_BYTE:
772 if (parameterizedType) {
773 JLocalAutoRef jo(
774 jni, jni->GetObjectField( java_data.l, field_id ) );
775 if ( jo.get() == 0 ) {
776 *static_cast<jbyte *>(p) = 0;
777 } else {
778 jvalue val;
779 val.l = jo.get();
780 map_to_uno(
781 jni, p, val, member_type, 0, assign, false,
782 true );
784 } else {
785 *static_cast<jbyte *>(p) = jni->GetByteField(
786 java_data.l, field_id );
788 break;
789 case typelib_TypeClass_SHORT:
790 case typelib_TypeClass_UNSIGNED_SHORT:
791 if (parameterizedType) {
792 JLocalAutoRef jo(
793 jni, jni->GetObjectField( java_data.l, field_id ) );
794 if ( jo.get() == 0 ) {
795 *static_cast<jshort *>(p) = 0;
796 } else {
797 jvalue val;
798 val.l = jo.get();
799 map_to_uno(
800 jni, p, val, member_type, 0, assign, false,
801 true );
803 } else {
804 *static_cast<jshort *>(p) = jni->GetShortField(
805 java_data.l, field_id );
807 break;
808 case typelib_TypeClass_LONG:
809 case typelib_TypeClass_UNSIGNED_LONG:
810 if (parameterizedType) {
811 JLocalAutoRef jo(
812 jni, jni->GetObjectField( java_data.l, field_id ) );
813 if ( jo.get() == 0 ) {
814 *static_cast<jint *>(p) = 0;
815 } else {
816 jvalue val;
817 val.l = jo.get();
818 map_to_uno(
819 jni, p, val, member_type, 0, assign, false,
820 true );
822 } else {
823 *static_cast<jint *>(p) = jni->GetIntField( java_data.l, field_id );
825 break;
826 case typelib_TypeClass_HYPER:
827 case typelib_TypeClass_UNSIGNED_HYPER:
828 if (parameterizedType) {
829 JLocalAutoRef jo(
830 jni, jni->GetObjectField( java_data.l, field_id ) );
831 if ( jo.get() == 0 ) {
832 *static_cast<jlong *>(p) = 0;
833 } else {
834 jvalue val;
835 val.l = jo.get();
836 map_to_uno(
837 jni, p, val, member_type, 0, assign, false,
838 true );
840 } else {
841 *static_cast<jlong *>(p) = jni->GetLongField(
842 java_data.l, field_id );
844 break;
845 case typelib_TypeClass_FLOAT:
846 if (parameterizedType) {
847 JLocalAutoRef jo(
848 jni, jni->GetObjectField( java_data.l, field_id ) );
849 if ( jo.get() == 0 ) {
850 *static_cast<jfloat *>(p) = 0;
851 } else {
852 jvalue val;
853 val.l = jo.get();
854 map_to_uno(
855 jni, p, val, member_type, 0, assign, false,
856 true );
858 } else {
859 *static_cast<jfloat *>(p) = jni->GetFloatField(
860 java_data.l, field_id );
862 break;
863 case typelib_TypeClass_DOUBLE:
864 if (parameterizedType) {
865 JLocalAutoRef jo(
866 jni, jni->GetObjectField( java_data.l, field_id ) );
867 if ( jo.get() == 0 ) {
868 *static_cast<jdouble *>(p) = 0;
869 } else {
870 jvalue val;
871 val.l = jo.get();
872 map_to_uno(
873 jni, p, val, member_type, 0, assign, false,
874 true );
876 } else {
877 *static_cast<jdouble *>(p) = jni->GetDoubleField(
878 java_data.l, field_id );
880 break;
881 default:
883 JLocalAutoRef jo_field( jni );
884 bool checkNull;
885 if (0 == field_id)
887 // special for Message: call Throwable.getMessage()
888 assert(
889 type_equals(
890 type,
891 getJniInfo()->m_Exception_type.getTypeLibType() )
892 || type_equals(
893 type,
894 getJniInfo()->m_RuntimeException_type.
895 getTypeLibType() ) );
896 assert( 0 == nPos ); // first member
897 // call getMessage()
898 jo_field.reset(
899 jni->CallObjectMethodA(
900 java_data.l,
901 getJniInfo()->m_method_Throwable_getMessage, 0 )
903 jni.ensure_no_exception();
904 checkNull = true;
906 else
908 jo_field.reset(
909 jni->GetObjectField( java_data.l, field_id ) );
910 checkNull = parameterizedType;
912 if (checkNull && !jo_field.is()) {
913 createDefaultUnoValue(jni, p, member_type, 0, assign);
914 } else {
915 jvalue val;
916 val.l = jo_field.get();
917 map_to_uno(
918 jni, p, val, member_type, 0,
919 assign, false /* no out param */ );
921 break;
926 catch (...)
928 if (! assign)
930 // cleanup
931 for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
933 void * p =
934 static_cast<char *>(uno_data) + comp_td->pMemberOffsets[ nCleanup ];
935 uno_type_destructData(
936 p, comp_td->ppTypeRefs[ nCleanup ], 0 );
938 if (0 != comp_td->pBaseTypeDescription)
940 uno_destructData(
941 uno_data, &comp_td->pBaseTypeDescription->aBase, 0 );
944 throw;
946 break;
948 case typelib_TypeClass_SEQUENCE:
950 JLocalAutoRef jo_out_holder( jni );
951 if (out_param)
953 jo_out_holder.reset(
954 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
955 jni.ensure_no_exception();
956 java_data.l = jo_out_holder.get();
958 if (0 == java_data.l)
960 throw BridgeRuntimeError(
961 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
962 + "] null-ref given!" + jni.get_stack_trace() );
965 TypeDescr td( type );
966 typelib_TypeDescriptionReference * element_type =
967 reinterpret_cast<typelib_IndirectTypeDescription *>(td.get())->pType;
969 std::unique_ptr< rtl_mem > seq;
970 sal_Int32 nElements = jni->GetArrayLength( static_cast<jarray>(java_data.l) );
972 switch (element_type->eTypeClass)
974 case typelib_TypeClass_CHAR:
975 seq.reset( seq_allocate( nElements, sizeof (sal_Unicode) ) );
976 jni->GetCharArrayRegion(
977 static_cast<jcharArray>(java_data.l), 0, nElements,
978 reinterpret_cast<jchar *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
979 jni.ensure_no_exception();
980 break;
981 case typelib_TypeClass_BOOLEAN:
982 seq.reset( seq_allocate( nElements, sizeof (sal_Bool) ) );
983 jni->GetBooleanArrayRegion(
984 static_cast<jbooleanArray>(java_data.l), 0, nElements,
985 reinterpret_cast<jboolean *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
986 jni.ensure_no_exception();
987 break;
988 case typelib_TypeClass_BYTE:
989 seq.reset( seq_allocate( nElements, sizeof (sal_Int8) ) );
990 jni->GetByteArrayRegion(
991 static_cast<jbyteArray>(java_data.l), 0, nElements,
992 reinterpret_cast<jbyte *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
993 jni.ensure_no_exception();
994 break;
995 case typelib_TypeClass_SHORT:
996 case typelib_TypeClass_UNSIGNED_SHORT:
997 seq.reset( seq_allocate( nElements, sizeof (sal_Int16) ) );
998 jni->GetShortArrayRegion(
999 static_cast<jshortArray>(java_data.l), 0, nElements,
1000 reinterpret_cast<jshort *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1001 jni.ensure_no_exception();
1002 break;
1003 case typelib_TypeClass_LONG:
1004 case typelib_TypeClass_UNSIGNED_LONG:
1005 seq.reset( seq_allocate( nElements, sizeof (sal_Int32) ) );
1006 jni->GetIntArrayRegion(
1007 static_cast<jintArray>(java_data.l), 0, nElements,
1008 reinterpret_cast<jint *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1009 jni.ensure_no_exception();
1010 break;
1011 case typelib_TypeClass_HYPER:
1012 case typelib_TypeClass_UNSIGNED_HYPER:
1013 seq.reset( seq_allocate( nElements, sizeof (sal_Int64) ) );
1014 jni->GetLongArrayRegion(
1015 static_cast<jlongArray>(java_data.l), 0, nElements,
1016 reinterpret_cast<jlong *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1017 jni.ensure_no_exception();
1018 break;
1019 case typelib_TypeClass_FLOAT:
1020 seq.reset( seq_allocate( nElements, sizeof (float) ) );
1021 jni->GetFloatArrayRegion(
1022 static_cast<jfloatArray>(java_data.l), 0, nElements,
1023 reinterpret_cast<jfloat *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1024 jni.ensure_no_exception();
1025 break;
1026 case typelib_TypeClass_DOUBLE:
1027 seq.reset( seq_allocate( nElements, sizeof (double) ) );
1028 jni->GetDoubleArrayRegion(
1029 static_cast<jdoubleArray>(java_data.l), 0, nElements,
1030 reinterpret_cast<jdouble *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1031 jni.ensure_no_exception();
1032 break;
1033 case typelib_TypeClass_STRING:
1034 case typelib_TypeClass_TYPE:
1035 case typelib_TypeClass_ANY:
1036 case typelib_TypeClass_ENUM:
1037 case typelib_TypeClass_STRUCT:
1038 case typelib_TypeClass_EXCEPTION:
1039 case typelib_TypeClass_SEQUENCE:
1040 case typelib_TypeClass_INTERFACE:
1042 TypeDescr element_td( element_type );
1043 seq.reset( seq_allocate( nElements, element_td.get()->nSize ) );
1045 JNI_type_info const * element_info;
1046 if (typelib_TypeClass_STRUCT == element_type->eTypeClass ||
1047 typelib_TypeClass_EXCEPTION == element_type->eTypeClass ||
1048 typelib_TypeClass_INTERFACE == element_type->eTypeClass)
1050 element_info =
1051 getJniInfo()->get_type_info( jni, element_td.get() );
1053 else
1055 element_info = 0;
1058 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1062 JLocalAutoRef jo(
1063 jni, jni->GetObjectArrayElement(
1064 static_cast<jobjectArray>(java_data.l), nPos ) );
1065 jni.ensure_no_exception();
1066 jvalue val;
1067 val.l = jo.get();
1068 void * p =
1069 reinterpret_cast<uno_Sequence *>(seq.get())->elements +
1070 (nPos * element_td.get()->nSize);
1071 map_to_uno(
1072 jni, p, val, element_td.get()->pWeakRef, element_info,
1073 false /* no assign */, false /* no out param */ );
1075 catch (...)
1077 // cleanup
1078 for ( sal_Int32 nCleanPos = 0;
1079 nCleanPos < nPos; ++nCleanPos )
1081 void * p =
1082 reinterpret_cast<uno_Sequence *>(seq.get())->elements +
1083 (nCleanPos * element_td.get()->nSize);
1084 uno_destructData( p, element_td.get(), 0 );
1086 throw;
1089 break;
1091 default:
1093 throw BridgeRuntimeError(
1094 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
1095 + "] unsupported sequence element type: "
1096 + OUString::unacquired( &element_type->pTypeName )
1097 + jni.get_stack_trace() );
1101 if (assign)
1102 uno_destructData( uno_data, td.get(), 0 );
1103 *static_cast<uno_Sequence **>(uno_data) = reinterpret_cast<uno_Sequence *>(seq.release());
1104 break;
1106 case typelib_TypeClass_INTERFACE:
1108 JLocalAutoRef jo_out_holder( jni );
1109 if (out_param)
1111 jo_out_holder.reset(
1112 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
1113 jni.ensure_no_exception();
1114 java_data.l = jo_out_holder.get();
1117 if (0 == java_data.l) // null-ref
1119 if (assign)
1121 uno_Interface * p = *static_cast<uno_Interface **>(uno_data);
1122 if (0 != p)
1123 (*p->release)( p );
1125 *static_cast<uno_Interface **>(uno_data) = 0;
1127 else
1129 if (0 == info)
1130 info = getJniInfo()->get_type_info( jni, type );
1131 JNI_interface_type_info const * iface_info =
1132 static_cast< JNI_interface_type_info const * >( info );
1133 uno_Interface * pUnoI = map_to_uno( jni, java_data.l, iface_info );
1134 if (assign)
1136 uno_Interface * p = *static_cast<uno_Interface **>(uno_data);
1137 if (0 != p)
1138 (*p->release)( p );
1140 *static_cast<uno_Interface **>(uno_data) = pUnoI;
1142 break;
1144 default:
1146 throw BridgeRuntimeError(
1147 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
1148 + "] unsupported type!" + jni.get_stack_trace() );
1155 void Bridge::map_to_java(
1156 JNI_context const & jni,
1157 jvalue * java_data, void const * uno_data,
1158 typelib_TypeDescriptionReference * type,
1159 JNI_type_info const * info /* maybe 0 */,
1160 bool in_param, bool out_param,
1161 bool special_wrapped_integral_types ) const
1163 // 4th param of Set*ArrayRegion changed from pointer to non-const to pointer
1164 // to const between <http://docs.oracle.com/javase/6/docs/technotes/guides/
1165 // jni/spec/functions.html#wp22933> and <http://docs.oracle.com/javase/7/
1166 // docs/technotes/guides/jni/spec/functions.html#wp22933>; work around that
1167 // difference in a way that doesn't trigger loplugin:redundantcast:
1168 void * data = const_cast<void *>(uno_data);
1170 switch (type->eTypeClass)
1172 case typelib_TypeClass_CHAR:
1173 if (out_param)
1175 if (0 == java_data->l)
1177 JLocalAutoRef jo_ar( jni, jni->NewCharArray( 1 ) );
1178 jni.ensure_no_exception();
1179 if (in_param)
1181 jni->SetCharArrayRegion(
1182 static_cast<jcharArray>(jo_ar.get()), 0, 1, static_cast<jchar *>(data) );
1183 jni.ensure_no_exception();
1185 java_data->l = jo_ar.release();
1187 else
1189 if (in_param)
1191 jni->SetCharArrayRegion(
1192 static_cast<jcharArray>(java_data->l), 0, 1, static_cast<jchar *>(data) );
1193 jni.ensure_no_exception();
1197 else if (special_wrapped_integral_types)
1199 jvalue arg;
1200 arg.c = *static_cast<jchar const *>(uno_data);
1201 java_data->l = jni->NewObjectA(
1202 getJniInfo()->m_class_Character,
1203 getJniInfo()->m_ctor_Character_with_char, &arg );
1204 jni.ensure_no_exception();
1206 else
1208 java_data->c = *static_cast<jchar const *>(uno_data);
1210 break;
1211 case typelib_TypeClass_BOOLEAN:
1212 if (out_param)
1214 if (0 == java_data->l)
1216 JLocalAutoRef jo_ar( jni, jni->NewBooleanArray( 1 ) );
1217 jni.ensure_no_exception();
1218 if (in_param)
1220 jni->SetBooleanArrayRegion(
1221 static_cast<jbooleanArray>(jo_ar.get()),
1222 0, 1, static_cast<jboolean *>(data) );
1223 jni.ensure_no_exception();
1225 java_data->l = jo_ar.release();
1227 else
1229 if (in_param)
1231 jni->SetBooleanArrayRegion(
1232 static_cast<jbooleanArray>(java_data->l),
1233 0, 1, static_cast<jboolean *>(data) );
1234 jni.ensure_no_exception();
1238 else if (special_wrapped_integral_types)
1240 jvalue arg;
1241 arg.z = *static_cast<jboolean const *>(uno_data);
1242 java_data->l = jni->NewObjectA(
1243 getJniInfo()->m_class_Boolean,
1244 getJniInfo()->m_ctor_Boolean_with_boolean, &arg );
1245 jni.ensure_no_exception();
1247 else
1249 java_data->z = *static_cast<jboolean const *>(uno_data);
1251 break;
1252 case typelib_TypeClass_BYTE:
1253 if (out_param)
1255 if (0 == java_data->l)
1257 JLocalAutoRef jo_ar( jni, jni->NewByteArray( 1 ) );
1258 jni.ensure_no_exception();
1259 if (in_param)
1261 jni->SetByteArrayRegion(
1262 static_cast<jbyteArray>(jo_ar.get()), 0, 1, static_cast<jbyte *>(data) );
1263 jni.ensure_no_exception();
1265 java_data->l = jo_ar.release();
1267 else
1269 if (in_param)
1271 jni->SetByteArrayRegion(
1272 static_cast<jbyteArray>(java_data->l), 0, 1, static_cast<jbyte *>(data) );
1273 jni.ensure_no_exception();
1277 else if (special_wrapped_integral_types)
1279 jvalue arg;
1280 arg.b = *static_cast<jbyte const *>(uno_data);
1281 java_data->l = jni->NewObjectA(
1282 getJniInfo()->m_class_Byte,
1283 getJniInfo()->m_ctor_Byte_with_byte, &arg );
1284 jni.ensure_no_exception();
1286 else
1288 java_data->b = *static_cast<jbyte const *>(uno_data);
1290 break;
1291 case typelib_TypeClass_SHORT:
1292 case typelib_TypeClass_UNSIGNED_SHORT:
1293 if (out_param)
1295 if (0 == java_data->l)
1297 JLocalAutoRef jo_ar( jni, jni->NewShortArray( 1 ) );
1298 jni.ensure_no_exception();
1299 if (in_param)
1301 jni->SetShortArrayRegion(
1302 static_cast<jshortArray>(jo_ar.get()), 0, 1, static_cast<jshort *>(data) );
1303 jni.ensure_no_exception();
1305 java_data->l = jo_ar.release();
1307 else
1309 if (in_param)
1311 jni->SetShortArrayRegion(
1312 static_cast<jshortArray>(java_data->l), 0, 1, static_cast<jshort *>(data) );
1313 jni.ensure_no_exception();
1317 else if (special_wrapped_integral_types)
1319 jvalue arg;
1320 arg.s = *static_cast<jshort const *>(uno_data);
1321 java_data->l = jni->NewObjectA(
1322 getJniInfo()->m_class_Short,
1323 getJniInfo()->m_ctor_Short_with_short, &arg );
1324 jni.ensure_no_exception();
1326 else
1328 java_data->s = *static_cast<jshort const *>(uno_data);
1330 break;
1331 case typelib_TypeClass_LONG:
1332 case typelib_TypeClass_UNSIGNED_LONG:
1333 if (out_param)
1335 if (0 == java_data->l)
1337 JLocalAutoRef jo_ar( jni, jni->NewIntArray( 1 ) );
1338 jni.ensure_no_exception();
1339 if (in_param)
1341 jni->SetIntArrayRegion(
1342 static_cast<jintArray>(jo_ar.get()), 0, 1, static_cast<jint *>(data) );
1343 jni.ensure_no_exception();
1345 java_data->l = jo_ar.release();
1347 else
1349 if (in_param)
1351 jni->SetIntArrayRegion(
1352 static_cast<jintArray>(java_data->l), 0, 1, static_cast<jint *>(data) );
1353 jni.ensure_no_exception();
1357 else if (special_wrapped_integral_types)
1359 jvalue arg;
1360 arg.i = *static_cast<jint const *>(uno_data);
1361 java_data->l = jni->NewObjectA(
1362 getJniInfo()->m_class_Integer,
1363 getJniInfo()->m_ctor_Integer_with_int, &arg );
1364 jni.ensure_no_exception();
1366 else
1368 java_data->i = *static_cast<jint const *>(uno_data);
1370 break;
1371 case typelib_TypeClass_HYPER:
1372 case typelib_TypeClass_UNSIGNED_HYPER:
1373 if (out_param)
1375 if (0 == java_data->l)
1377 JLocalAutoRef jo_ar( jni, jni->NewLongArray( 1 ) );
1378 jni.ensure_no_exception();
1379 if (in_param)
1381 jni->SetLongArrayRegion(
1382 static_cast<jlongArray>(jo_ar.get()), 0, 1, static_cast<jlong *>(data) );
1383 jni.ensure_no_exception();
1385 java_data->l = jo_ar.release();
1387 else
1389 if (in_param)
1391 jni->SetLongArrayRegion(
1392 static_cast<jlongArray>(java_data->l), 0, 1, static_cast<jlong *>(data) );
1393 jni.ensure_no_exception();
1397 else if (special_wrapped_integral_types)
1399 jvalue arg;
1400 arg.j = *static_cast<jlong const *>(uno_data);
1401 java_data->l = jni->NewObjectA(
1402 getJniInfo()->m_class_Long,
1403 getJniInfo()->m_ctor_Long_with_long, &arg );
1404 jni.ensure_no_exception();
1406 else
1408 java_data->j = *static_cast<jlong const *>(uno_data);
1410 break;
1411 case typelib_TypeClass_FLOAT:
1412 if (out_param)
1414 if (0 == java_data->l)
1416 JLocalAutoRef jo_ar( jni, jni->NewFloatArray( 1 ) );
1417 jni.ensure_no_exception();
1418 if (in_param)
1420 jni->SetFloatArrayRegion(
1421 static_cast<jfloatArray>(jo_ar.get()), 0, 1, static_cast<jfloat *>(data) );
1422 jni.ensure_no_exception();
1424 java_data->l = jo_ar.release();
1426 else
1428 if (in_param)
1430 jni->SetFloatArrayRegion(
1431 static_cast<jfloatArray>(java_data->l), 0, 1, static_cast<jfloat *>(data) );
1432 jni.ensure_no_exception();
1436 else if (special_wrapped_integral_types)
1438 jvalue arg;
1439 arg.f = *static_cast<jfloat const *>(uno_data);
1440 java_data->l = jni->NewObjectA(
1441 getJniInfo()->m_class_Float,
1442 getJniInfo()->m_ctor_Float_with_float, &arg );
1443 jni.ensure_no_exception();
1445 else
1447 java_data->f = *static_cast<jfloat const *>(uno_data);
1449 break;
1450 case typelib_TypeClass_DOUBLE:
1451 if (out_param)
1453 if (0 == java_data->l)
1455 JLocalAutoRef jo_ar( jni, jni->NewDoubleArray( 1 ) );
1456 jni.ensure_no_exception();
1457 if (in_param)
1459 jni->SetDoubleArrayRegion(
1460 static_cast<jdoubleArray>(jo_ar.get()),
1461 0, 1, static_cast<jdouble *>(data) );
1462 jni.ensure_no_exception();
1464 java_data->l = jo_ar.release();
1466 else
1468 if (in_param)
1470 jni->SetDoubleArrayRegion(
1471 static_cast<jdoubleArray>(java_data->l),
1472 0, 1, static_cast<jdouble *>(data) );
1473 jni.ensure_no_exception();
1477 else if (special_wrapped_integral_types)
1479 jvalue arg;
1480 arg.d = *static_cast<double const *>(uno_data);
1481 java_data->l = jni->NewObjectA(
1482 getJniInfo()->m_class_Double,
1483 getJniInfo()->m_ctor_Double_with_double, &arg );
1484 jni.ensure_no_exception();
1486 else
1488 java_data->d = *static_cast<jdouble const *>(uno_data);
1490 break;
1491 case typelib_TypeClass_STRING:
1493 if (out_param)
1495 JLocalAutoRef jo_in( jni );
1496 if (in_param)
1498 jo_in.reset(
1499 ustring_to_jstring(
1500 jni, *static_cast<rtl_uString * const *>(uno_data) ) );
1502 if (0 == java_data->l)
1504 java_data->l = jni->NewObjectArray(
1505 1, getJniInfo()->m_class_String, jo_in.get() );
1506 jni.ensure_no_exception();
1508 else
1510 jni->SetObjectArrayElement(
1511 static_cast<jobjectArray>(java_data->l), 0, jo_in.get() );
1512 jni.ensure_no_exception();
1515 else
1517 assert( in_param );
1518 java_data->l =
1519 ustring_to_jstring( jni, *static_cast<rtl_uString * const *>(uno_data) );
1521 break;
1523 case typelib_TypeClass_TYPE:
1525 if (out_param)
1527 JLocalAutoRef jo_in( jni );
1528 if (in_param)
1530 jo_in.reset(
1531 create_type(
1532 jni,
1533 *static_cast<typelib_TypeDescriptionReference * const *>(uno_data) )
1536 if (0 == java_data->l)
1538 java_data->l = jni->NewObjectArray(
1539 1, getJniInfo()->m_class_Type, jo_in.get() );
1540 jni.ensure_no_exception();
1542 else
1544 jni->SetObjectArrayElement(
1545 static_cast<jobjectArray>(java_data->l), 0, jo_in.get() );
1546 jni.ensure_no_exception();
1549 else
1551 assert( in_param );
1552 java_data->l =
1553 create_type(
1554 jni,
1555 *static_cast<typelib_TypeDescriptionReference * const *>(uno_data) );
1557 break;
1559 case typelib_TypeClass_ANY:
1561 JLocalAutoRef jo_any( jni );
1562 if (in_param)
1564 uno_Any const * pAny = static_cast<uno_Any const *>(uno_data);
1565 switch (pAny->pType->eTypeClass)
1567 case typelib_TypeClass_VOID:
1568 jo_any.reset(
1569 jni->NewLocalRef( getJniInfo()->m_object_Any_VOID ) );
1570 break;
1571 case typelib_TypeClass_UNSIGNED_SHORT:
1573 jvalue args[ 2 ];
1574 args[ 0 ].s = *static_cast<jshort const *>(pAny->pData);
1575 JLocalAutoRef jo_val(
1576 jni, jni->NewObjectA(
1577 getJniInfo()->m_class_Short,
1578 getJniInfo()->m_ctor_Short_with_short, args ) );
1579 jni.ensure_no_exception();
1580 // box up in com.sun.star.uno.Any
1581 args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_SHORT;
1582 args[ 1 ].l = jo_val.get();
1583 jo_any.reset(
1584 jni->NewObjectA(
1585 getJniInfo()->m_class_Any,
1586 getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1587 jni.ensure_no_exception();
1588 break;
1590 case typelib_TypeClass_UNSIGNED_LONG:
1592 jvalue args[ 2 ];
1593 args[ 0 ].i = *static_cast<jint const *>(pAny->pData);
1594 JLocalAutoRef jo_val(
1595 jni, jni->NewObjectA(
1596 getJniInfo()->m_class_Integer,
1597 getJniInfo()->m_ctor_Integer_with_int, args ) );
1598 jni.ensure_no_exception();
1599 // box up in com.sun.star.uno.Any
1600 args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_LONG;
1601 args[ 1 ].l = jo_val.get();
1602 jo_any.reset(
1603 jni->NewObjectA(
1604 getJniInfo()->m_class_Any,
1605 getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1606 jni.ensure_no_exception();
1607 break;
1609 case typelib_TypeClass_UNSIGNED_HYPER:
1611 jvalue args[ 2 ];
1612 args[ 0 ].j = *static_cast<jlong const *>(pAny->pData);
1613 JLocalAutoRef jo_val(
1614 jni, jni->NewObjectA(
1615 getJniInfo()->m_class_Long,
1616 getJniInfo()->m_ctor_Long_with_long, args ) );
1617 jni.ensure_no_exception();
1618 // box up in com.sun.star.uno.Any
1619 args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_HYPER;
1620 args[ 1 ].l = jo_val.get();
1621 jo_any.reset(
1622 jni->NewObjectA(
1623 getJniInfo()->m_class_Any,
1624 getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1625 jni.ensure_no_exception();
1626 break;
1628 case typelib_TypeClass_STRING: // opt strings
1629 jo_any.reset( ustring_to_jstring(
1630 jni, static_cast<rtl_uString *>(pAny->pReserved) ) );
1631 break;
1632 case typelib_TypeClass_SEQUENCE:
1634 jvalue java_data2;
1635 // prefetch sequence td
1636 TypeDescr seq_td( pAny->pType );
1637 map_to_java(
1638 jni, &java_data2, pAny->pData, seq_td.get()->pWeakRef, 0,
1639 true /* in */, false /* no out */,
1640 true /* create integral wrappers */ );
1641 jo_any.reset( java_data2.l );
1643 // determine inner element type
1644 ::com::sun::star::uno::Type element_type(
1645 reinterpret_cast<typelib_IndirectTypeDescription *>(seq_td.get())->pType );
1646 while (typelib_TypeClass_SEQUENCE ==
1647 element_type.getTypeLibType()->eTypeClass)
1649 TypeDescr element_td( element_type.getTypeLibType() );
1650 typelib_typedescriptionreference_assign(
1651 reinterpret_cast< typelib_TypeDescriptionReference ** >(
1652 &element_type ),
1653 reinterpret_cast<typelib_IndirectTypeDescription *>(element_td.get())
1654 ->pType );
1656 // box up only if unsigned element type
1657 switch (element_type.getTypeLibType()->eTypeClass)
1659 case typelib_TypeClass_UNSIGNED_SHORT:
1660 case typelib_TypeClass_UNSIGNED_LONG:
1661 case typelib_TypeClass_UNSIGNED_HYPER:
1663 jvalue args[ 2 ];
1664 JLocalAutoRef jo_type(
1665 jni, create_type( jni, seq_td.get()->pWeakRef ) );
1666 args[ 0 ].l = jo_type.get();
1667 args[ 1 ].l = jo_any.get();
1668 jo_any.reset(
1669 jni->NewObjectA(
1670 getJniInfo()->m_class_Any,
1671 getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1672 jni.ensure_no_exception();
1673 break;
1675 default:
1676 break;
1678 break;
1680 case typelib_TypeClass_INTERFACE:
1682 uno_Interface * pUnoI = static_cast<uno_Interface *>(pAny->pReserved);
1683 if (is_XInterface( pAny->pType ))
1685 if (0 != pUnoI)
1687 jo_any.reset(
1688 map_to_java(
1689 jni, pUnoI,
1690 getJniInfo()->m_XInterface_type_info ) );
1692 // else: empty XInterface ref maps to null-ref
1694 else
1696 JNI_interface_type_info const * iface_info =
1697 static_cast< JNI_interface_type_info const * >(
1698 getJniInfo()->get_type_info( jni, pAny->pType ) );
1699 if (0 != pUnoI)
1701 jo_any.reset( map_to_java( jni, pUnoI, iface_info ) );
1703 // box up in com.sun.star.uno.Any
1704 jvalue args[ 2 ];
1705 args[ 0 ].l = iface_info->m_type;
1706 args[ 1 ].l = jo_any.get();
1707 jo_any.reset(
1708 jni->NewObjectA(
1709 getJniInfo()->m_class_Any,
1710 getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1711 jni.ensure_no_exception();
1713 break;
1715 case typelib_TypeClass_STRUCT:
1717 // Do not lose information about type arguments of instantiated
1718 // polymorphic struct types:
1719 OUString const & name = OUString::unacquired(
1720 &pAny->pType->pTypeName);
1721 assert(!name.isEmpty());
1722 if (name[name.getLength() - 1] == '>')
1724 // Box up in com.sun.star.uno.Any:
1725 JLocalAutoRef jo_type(jni, create_type(jni, pAny->pType));
1726 jvalue java_data2;
1727 map_to_java(
1728 jni, &java_data2, pAny->pData, pAny->pType, 0, true,
1729 false);
1730 jo_any.reset(java_data2.l);
1731 jvalue args[2];
1732 args[0].l = jo_type.get();
1733 args[1].l = jo_any.get();
1734 jo_any.reset(
1735 jni->NewObjectA(
1736 getJniInfo()->m_class_Any,
1737 getJniInfo()->m_ctor_Any_with_Type_Object, args));
1738 jni.ensure_no_exception();
1739 break;
1741 // fall through
1743 default:
1745 jvalue java_data2;
1746 map_to_java(
1747 jni, &java_data2, pAny->pData, pAny->pType, 0,
1748 true /* in */, false /* no out */,
1749 true /* create integral wrappers */ );
1750 jo_any.reset( java_data2.l );
1751 break;
1756 if (out_param)
1758 if (0 == java_data->l)
1760 java_data->l = jni->NewObjectArray(
1761 1, getJniInfo()->m_class_Object, jo_any.get() );
1762 jni.ensure_no_exception();
1764 else
1766 jni->SetObjectArrayElement(
1767 static_cast<jobjectArray>(java_data->l), 0, jo_any.get() );
1768 jni.ensure_no_exception();
1771 else
1773 java_data->l = jo_any.release();
1775 break;
1777 case typelib_TypeClass_ENUM:
1779 OUString const & type_name = OUString::unacquired( &type->pTypeName );
1780 OString class_name(
1781 OUStringToOString( type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
1782 JLocalAutoRef jo_enum_class(
1783 jni, find_class( jni, class_name.getStr() ) );
1785 JLocalAutoRef jo_enum( jni );
1786 if (in_param)
1788 // call static <enum_class>.fromInt( int )
1789 OStringBuffer sig_buf( 5 + class_name.getLength() );
1790 sig_buf.append( "(I)L" );
1791 sig_buf.append( class_name.replace( '.', '/' ) );
1792 sig_buf.append( ';' );
1793 OString sig( sig_buf.makeStringAndClear() );
1794 jmethodID method_id = jni->GetStaticMethodID(
1795 static_cast<jclass>(jo_enum_class.get()), "fromInt", sig.getStr() );
1796 jni.ensure_no_exception();
1797 assert( 0 != method_id );
1799 jvalue arg;
1800 arg.i = *static_cast<jint const *>(uno_data);
1801 jo_enum.reset(
1802 jni->CallStaticObjectMethodA(
1803 static_cast<jclass>(jo_enum_class.get()), method_id, &arg ) );
1804 jni.ensure_no_exception();
1806 if (out_param)
1808 if (0 == java_data->l)
1810 java_data->l = jni->NewObjectArray(
1811 1, static_cast<jclass>(jo_enum_class.get()), jo_enum.get() );
1812 jni.ensure_no_exception();
1814 else
1816 jni->SetObjectArrayElement(
1817 static_cast<jobjectArray>(java_data->l), 0, jo_enum.get() );
1818 jni.ensure_no_exception();
1821 else
1823 java_data->l = jo_enum.release();
1825 break;
1827 case typelib_TypeClass_STRUCT:
1828 case typelib_TypeClass_EXCEPTION:
1830 if (0 == info)
1831 info = getJniInfo()->get_type_info( jni, type );
1832 JNI_compound_type_info const * comp_info =
1833 static_cast< JNI_compound_type_info const * >( info );
1835 JLocalAutoRef jo_comp( jni );
1836 if (in_param)
1838 if (typelib_TypeClass_EXCEPTION == type->eTypeClass)
1840 JLocalAutoRef jo_message(
1841 jni, ustring_to_jstring( jni, *static_cast<rtl_uString * const *>(uno_data) ) );
1842 jvalue arg;
1843 arg.l = jo_message.get();
1844 jo_comp.reset(
1845 jni->NewObjectA(
1846 comp_info->m_class, comp_info->m_exc_ctor, &arg ) );
1847 jni.ensure_no_exception();
1849 else
1851 jo_comp.reset( jni->AllocObject( comp_info->m_class ) );
1852 jni.ensure_no_exception();
1855 for ( JNI_compound_type_info const * linfo = comp_info;
1856 0 != linfo;
1857 linfo = static_cast< JNI_compound_type_info const * >(
1858 linfo->m_base ) )
1860 typelib_CompoundTypeDescription * comp_td =
1861 reinterpret_cast<typelib_CompoundTypeDescription *>(linfo->m_td.get());
1862 typelib_TypeDescriptionReference ** ppMemberTypeRefs =
1863 comp_td->ppTypeRefs;
1864 sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
1865 bool polymorphic
1866 = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
1867 && reinterpret_cast< typelib_StructTypeDescription * >(
1868 comp_td)->pParameterizedTypes != 0;
1869 for ( sal_Int32 nPos = comp_td->nMembers; nPos--; )
1871 jfieldID field_id = linfo->m_fields[ nPos ];
1872 if (0 != field_id)
1874 void const * p =
1875 static_cast<char const *>(uno_data) + pMemberOffsets[ nPos ];
1876 typelib_TypeDescriptionReference * member_type =
1877 ppMemberTypeRefs[ nPos ];
1878 bool parameterizedType = polymorphic
1879 && (reinterpret_cast<
1880 typelib_StructTypeDescription * >(comp_td)->
1881 pParameterizedTypes[nPos]);
1882 switch (member_type->eTypeClass)
1884 case typelib_TypeClass_CHAR:
1885 if (parameterizedType) {
1886 jvalue arg;
1887 arg.c = *static_cast<jchar const *>(p);
1888 JLocalAutoRef jo(
1889 jni,
1890 jni->NewObjectA(
1891 getJniInfo()->m_class_Character,
1892 getJniInfo()->m_ctor_Character_with_char,
1893 &arg ) );
1894 jni.ensure_no_exception();
1895 jni->SetObjectField(
1896 jo_comp.get(), field_id, jo.get() );
1897 } else {
1898 jni->SetCharField(
1899 jo_comp.get(),
1900 field_id, *static_cast<jchar const *>(p) );
1902 break;
1903 case typelib_TypeClass_BOOLEAN:
1904 if (parameterizedType) {
1905 jvalue arg;
1906 arg.z = *static_cast<jboolean const *>(p);
1907 JLocalAutoRef jo(
1908 jni,
1909 jni->NewObjectA(
1910 getJniInfo()->m_class_Boolean,
1911 getJniInfo()->m_ctor_Boolean_with_boolean,
1912 &arg ) );
1913 jni.ensure_no_exception();
1914 jni->SetObjectField(
1915 jo_comp.get(), field_id, jo.get() );
1916 } else {
1917 jni->SetBooleanField(
1918 jo_comp.get(),
1919 field_id, *static_cast<jboolean const *>(p) );
1921 break;
1922 case typelib_TypeClass_BYTE:
1923 if (parameterizedType) {
1924 jvalue arg;
1925 arg.b = *static_cast<jbyte const *>(p);
1926 JLocalAutoRef jo(
1927 jni,
1928 jni->NewObjectA(
1929 getJniInfo()->m_class_Byte,
1930 getJniInfo()->m_ctor_Byte_with_byte,
1931 &arg ) );
1932 jni.ensure_no_exception();
1933 jni->SetObjectField(
1934 jo_comp.get(), field_id, jo.get() );
1935 } else {
1936 jni->SetByteField(
1937 jo_comp.get(),
1938 field_id, *static_cast<jbyte const *>(p) );
1940 break;
1941 case typelib_TypeClass_SHORT:
1942 case typelib_TypeClass_UNSIGNED_SHORT:
1943 if (parameterizedType) {
1944 jvalue arg;
1945 arg.s = *static_cast<jshort const *>(p);
1946 JLocalAutoRef jo(
1947 jni,
1948 jni->NewObjectA(
1949 getJniInfo()->m_class_Short,
1950 getJniInfo()->m_ctor_Short_with_short,
1951 &arg ) );
1952 jni.ensure_no_exception();
1953 jni->SetObjectField(
1954 jo_comp.get(), field_id, jo.get() );
1955 } else {
1956 jni->SetShortField(
1957 jo_comp.get(),
1958 field_id, *static_cast<jshort const *>(p) );
1960 break;
1961 case typelib_TypeClass_LONG:
1962 case typelib_TypeClass_UNSIGNED_LONG:
1963 if (parameterizedType) {
1964 jvalue arg;
1965 arg.i = *static_cast<jint const *>(p);
1966 JLocalAutoRef jo(
1967 jni,
1968 jni->NewObjectA(
1969 getJniInfo()->m_class_Integer,
1970 getJniInfo()->m_ctor_Integer_with_int,
1971 &arg ) );
1972 jni.ensure_no_exception();
1973 jni->SetObjectField(
1974 jo_comp.get(), field_id, jo.get() );
1975 } else {
1976 jni->SetIntField(
1977 jo_comp.get(),
1978 field_id, *static_cast<jint const *>(p) );
1980 break;
1981 case typelib_TypeClass_HYPER:
1982 case typelib_TypeClass_UNSIGNED_HYPER:
1983 if (parameterizedType) {
1984 jvalue arg;
1985 arg.j = *static_cast<jlong const *>(p);
1986 JLocalAutoRef jo(
1987 jni,
1988 jni->NewObjectA(
1989 getJniInfo()->m_class_Long,
1990 getJniInfo()->m_ctor_Long_with_long,
1991 &arg ) );
1992 jni.ensure_no_exception();
1993 jni->SetObjectField(
1994 jo_comp.get(), field_id, jo.get() );
1995 } else {
1996 jni->SetLongField(
1997 jo_comp.get(),
1998 field_id, *static_cast<jlong const *>(p) );
2000 break;
2001 case typelib_TypeClass_FLOAT:
2002 if (parameterizedType) {
2003 jvalue arg;
2004 arg.f = *static_cast<jfloat const *>(p);
2005 JLocalAutoRef jo(
2006 jni,
2007 jni->NewObjectA(
2008 getJniInfo()->m_class_Float,
2009 getJniInfo()->m_ctor_Float_with_float,
2010 &arg ) );
2011 jni.ensure_no_exception();
2012 jni->SetObjectField(
2013 jo_comp.get(), field_id, jo.get() );
2014 } else {
2015 jni->SetFloatField(
2016 jo_comp.get(),
2017 field_id, *static_cast<jfloat const *>(p) );
2019 break;
2020 case typelib_TypeClass_DOUBLE:
2021 if (parameterizedType) {
2022 jvalue arg;
2023 arg.d = *static_cast<jdouble const *>(p);
2024 JLocalAutoRef jo(
2025 jni,
2026 jni->NewObjectA(
2027 getJniInfo()->m_class_Double,
2028 getJniInfo()->m_ctor_Double_with_double,
2029 &arg ) );
2030 jni.ensure_no_exception();
2031 jni->SetObjectField(
2032 jo_comp.get(), field_id, jo.get() );
2033 } else {
2034 jni->SetDoubleField(
2035 jo_comp.get(),
2036 field_id, *static_cast<jdouble const *>(p) );
2038 break;
2039 case typelib_TypeClass_STRING: // string opt here
2041 JLocalAutoRef jo_string(
2042 jni, ustring_to_jstring(
2043 jni, *static_cast<rtl_uString * const *>(p) ) );
2044 jni->SetObjectField(
2045 jo_comp.get(), field_id, jo_string.get() );
2046 break;
2048 default:
2050 jvalue java_data2;
2051 map_to_java(
2052 jni, &java_data2, p, member_type, 0,
2053 true /* in */, false /* no out */ );
2054 JLocalAutoRef jo_obj( jni, java_data2.l );
2055 jni->SetObjectField(
2056 jo_comp.get(), field_id, jo_obj.get() );
2057 break;
2064 if (out_param)
2066 if (0 == java_data->l)
2068 java_data->l =
2069 jni->NewObjectArray( 1, comp_info->m_class, jo_comp.get() );
2070 jni.ensure_no_exception();
2072 else
2074 jni->SetObjectArrayElement(
2075 static_cast<jobjectArray>(java_data->l), 0, jo_comp.get() );
2076 jni.ensure_no_exception();
2079 else
2081 java_data->l = jo_comp.release();
2083 break;
2085 case typelib_TypeClass_SEQUENCE:
2087 // xxx todo: possible opt for pure out sequences
2088 JLocalAutoRef jo_ar( jni );
2090 sal_Int32 nElements;
2091 uno_Sequence * seq = 0;
2092 if (in_param)
2094 seq = *static_cast<uno_Sequence * const *>(uno_data);
2095 nElements = seq->nElements;
2097 else
2099 nElements = 0;
2102 TypeDescr td( type );
2103 typelib_TypeDescriptionReference * element_type =
2104 reinterpret_cast<typelib_IndirectTypeDescription *>(td.get())->pType;
2106 switch (element_type->eTypeClass)
2108 case typelib_TypeClass_CHAR:
2109 jo_ar.reset( jni->NewCharArray( nElements ) );
2110 jni.ensure_no_exception();
2111 if (0 < nElements)
2113 jni->SetCharArrayRegion(
2114 static_cast<jcharArray>(jo_ar.get()),
2115 0, nElements, reinterpret_cast<jchar *>(seq->elements) );
2116 jni.ensure_no_exception();
2118 break;
2119 case typelib_TypeClass_BOOLEAN:
2120 jo_ar.reset( jni->NewBooleanArray( nElements ) );
2121 jni.ensure_no_exception();
2122 if (0 < nElements)
2124 jni->SetBooleanArrayRegion(
2125 static_cast<jbooleanArray>(jo_ar.get()),
2126 0, nElements, reinterpret_cast<jboolean *>(seq->elements) );
2127 jni.ensure_no_exception();
2129 break;
2130 case typelib_TypeClass_BYTE:
2131 jo_ar.reset( jni->NewByteArray( nElements ) );
2132 jni.ensure_no_exception();
2133 if (0 < nElements)
2135 jni->SetByteArrayRegion(
2136 static_cast<jbyteArray>(jo_ar.get()),
2137 0, nElements, reinterpret_cast<jbyte *>(seq->elements) );
2138 jni.ensure_no_exception();
2140 break;
2141 case typelib_TypeClass_SHORT:
2142 case typelib_TypeClass_UNSIGNED_SHORT:
2143 jo_ar.reset( jni->NewShortArray( nElements ) );
2144 jni.ensure_no_exception();
2145 if (0 < nElements)
2147 jni->SetShortArrayRegion(
2148 static_cast<jshortArray>(jo_ar.get()),
2149 0, nElements, reinterpret_cast<jshort *>(seq->elements) );
2150 jni.ensure_no_exception();
2152 break;
2153 case typelib_TypeClass_LONG:
2154 case typelib_TypeClass_UNSIGNED_LONG:
2155 jo_ar.reset( jni->NewIntArray( nElements ) );
2156 jni.ensure_no_exception();
2157 if (0 < nElements)
2159 jni->SetIntArrayRegion(
2160 static_cast<jintArray>(jo_ar.get()),
2161 0, nElements, reinterpret_cast<jint *>(seq->elements) );
2162 jni.ensure_no_exception();
2164 break;
2165 case typelib_TypeClass_HYPER:
2166 case typelib_TypeClass_UNSIGNED_HYPER:
2167 jo_ar.reset( jni->NewLongArray( nElements ) );
2168 jni.ensure_no_exception();
2169 if (0 < nElements)
2171 jni->SetLongArrayRegion(
2172 static_cast<jlongArray>(jo_ar.get()),
2173 0, nElements, reinterpret_cast<jlong *>(seq->elements) );
2174 jni.ensure_no_exception();
2176 break;
2177 case typelib_TypeClass_FLOAT:
2178 jo_ar.reset( jni->NewFloatArray( nElements ) );
2179 jni.ensure_no_exception();
2180 if (0 < nElements)
2182 jni->SetFloatArrayRegion(
2183 static_cast<jfloatArray>(jo_ar.get()),
2184 0, nElements, reinterpret_cast<jfloat *>(seq->elements) );
2185 jni.ensure_no_exception();
2187 break;
2188 case typelib_TypeClass_DOUBLE:
2189 jo_ar.reset( jni->NewDoubleArray( nElements ) );
2190 jni.ensure_no_exception();
2191 if (0 < nElements)
2193 jni->SetDoubleArrayRegion(
2194 static_cast<jdoubleArray>(jo_ar.get()),
2195 0, nElements, reinterpret_cast<jdouble *>(seq->elements) );
2196 jni.ensure_no_exception();
2198 break;
2199 case typelib_TypeClass_STRING:
2200 jo_ar.reset(
2201 jni->NewObjectArray(
2202 nElements, getJniInfo()->m_class_String, 0 ) );
2203 jni.ensure_no_exception();
2204 if (in_param)
2206 rtl_uString * const * pp =
2207 reinterpret_cast<rtl_uString * const *>(seq->elements);
2208 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2210 JLocalAutoRef jo_string(
2211 jni, ustring_to_jstring( jni, pp[ nPos ] ) );
2212 jni->SetObjectArrayElement(
2213 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_string.get() );
2214 jni.ensure_no_exception();
2217 break;
2218 case typelib_TypeClass_TYPE:
2219 jo_ar.reset(
2220 jni->NewObjectArray( nElements, getJniInfo()->m_class_Type, 0 ) );
2221 jni.ensure_no_exception();
2222 if (in_param)
2224 typelib_TypeDescriptionReference * const * pp =
2225 reinterpret_cast<typelib_TypeDescriptionReference * const *>(seq->elements);
2226 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2228 jvalue val;
2229 map_to_java(
2230 jni, &val, &pp[ nPos ], element_type, 0,
2231 true /* in */, false /* no out */ );
2232 JLocalAutoRef jo_element( jni, val.l );
2233 jni->SetObjectArrayElement(
2234 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2235 jni.ensure_no_exception();
2238 break;
2239 case typelib_TypeClass_ANY:
2240 jo_ar.reset(
2241 jni->NewObjectArray(
2242 nElements, getJniInfo()->m_class_Object, 0 ) );
2243 jni.ensure_no_exception();
2244 if (in_param)
2246 uno_Any const * p = reinterpret_cast<uno_Any const *>(seq->elements);
2247 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2249 jvalue val;
2250 map_to_java(
2251 jni, &val, &p[ nPos ], element_type, 0,
2252 true /* in */, false /* no out */ );
2253 JLocalAutoRef jo_element( jni, val.l );
2254 jni->SetObjectArrayElement(
2255 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2256 jni.ensure_no_exception();
2259 break;
2260 case typelib_TypeClass_ENUM:
2262 OUString const & element_type_name =
2263 OUString::unacquired( &element_type->pTypeName );
2264 OString class_name(
2265 OUStringToOString(
2266 element_type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
2267 JLocalAutoRef jo_enum_class(
2268 jni, find_class( jni, class_name.getStr() ) );
2270 jo_ar.reset(
2271 jni->NewObjectArray(
2272 nElements, static_cast<jclass>(jo_enum_class.get()), 0 ) );
2273 jni.ensure_no_exception();
2275 if (0 < nElements)
2277 // call static <enum_class>.fromInt( int )
2278 OStringBuffer sig_buf( 5 + class_name.getLength() );
2279 sig_buf.append( "(I)L" );
2280 sig_buf.append( class_name.replace( '.', '/' ) );
2281 sig_buf.append( ';' );
2282 OString sig( sig_buf.makeStringAndClear() );
2283 jmethodID method_id = jni->GetStaticMethodID(
2284 static_cast<jclass>(jo_enum_class.get()), "fromInt", sig.getStr() );
2285 jni.ensure_no_exception();
2286 assert( 0 != method_id );
2288 sal_Int32 const * p = reinterpret_cast<sal_Int32 const *>(seq->elements);
2289 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2291 jvalue arg;
2292 arg.i = p[ nPos ];
2293 JLocalAutoRef jo_enum(
2294 jni, jni->CallStaticObjectMethodA(
2295 static_cast<jclass>(jo_enum_class.get()), method_id, &arg ) );
2296 jni.ensure_no_exception();
2297 jni->SetObjectArrayElement(
2298 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_enum.get() );
2299 jni.ensure_no_exception();
2302 break;
2304 case typelib_TypeClass_STRUCT:
2305 case typelib_TypeClass_EXCEPTION:
2307 JNI_type_info const * element_info =
2308 getJniInfo()->get_type_info( jni, element_type );
2310 jo_ar.reset(
2311 jni->NewObjectArray( nElements, element_info->m_class, 0 ) );
2312 jni.ensure_no_exception();
2314 if (0 < nElements)
2316 char * p = const_cast<char *>(seq->elements);
2317 sal_Int32 nSize = element_info->m_td.get()->nSize;
2318 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2320 jvalue val;
2321 map_to_java(
2322 jni, &val, p + (nSize * nPos),
2323 element_type, element_info,
2324 true /* in */, false /* no out */ );
2325 JLocalAutoRef jo_element( jni, val.l );
2326 jni->SetObjectArrayElement(
2327 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2328 jni.ensure_no_exception();
2331 break;
2333 case typelib_TypeClass_SEQUENCE:
2335 OStringBuffer buf( 64 );
2336 JNI_info::append_sig(
2337 &buf, element_type, false /* use class XInterface */,
2338 false /* '.' instead of '/' */ );
2339 OString class_name( buf.makeStringAndClear() );
2340 JLocalAutoRef jo_seq_class(
2341 jni, find_class( jni, class_name.getStr() ) );
2343 jo_ar.reset(
2344 jni->NewObjectArray(
2345 nElements, static_cast<jclass>(jo_seq_class.get()), 0 ) );
2346 jni.ensure_no_exception();
2348 if (0 < nElements)
2350 TypeDescr element_td( element_type );
2351 uno_Sequence * const * elements = reinterpret_cast<uno_Sequence * const *>(seq->elements);
2352 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2354 jvalue java_data2;
2355 map_to_java(
2356 jni, &java_data2, elements + nPos, element_type, 0,
2357 true /* in */, false /* no out */ );
2358 JLocalAutoRef jo_seq( jni, java_data2.l );
2359 jni->SetObjectArrayElement(
2360 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_seq.get() );
2361 jni.ensure_no_exception();
2364 break;
2366 case typelib_TypeClass_INTERFACE:
2368 JNI_interface_type_info const * iface_info =
2369 static_cast< JNI_interface_type_info const * >(
2370 getJniInfo()->get_type_info( jni, element_type ) );
2372 jo_ar.reset(
2373 jni->NewObjectArray( nElements, iface_info->m_class, 0 ) );
2374 jni.ensure_no_exception();
2376 if (0 < nElements)
2378 uno_Interface * const * pp = reinterpret_cast<uno_Interface * const *>(seq->elements);
2379 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2381 uno_Interface * pUnoI = pp[ nPos ];
2382 if (0 != pUnoI)
2384 JLocalAutoRef jo_element(
2385 jni, map_to_java( jni, pUnoI, iface_info ) );
2386 jni->SetObjectArrayElement(
2387 static_cast<jobjectArray>(jo_ar.get()),
2388 nPos, jo_element.get() );
2389 jni.ensure_no_exception();
2393 break;
2395 default:
2397 throw BridgeRuntimeError(
2398 "[map_to_java():" + OUString::unacquired( &type->pTypeName )
2399 + "] unsupported element type: "
2400 + OUString::unacquired( &element_type->pTypeName )
2401 + jni.get_stack_trace() );
2405 if (out_param)
2407 if (0 == java_data->l)
2409 JLocalAutoRef jo_element_class(
2410 jni, jni->GetObjectClass( jo_ar.get() ) );
2411 if (in_param)
2413 java_data->l = jni->NewObjectArray(
2414 1, static_cast<jclass>(jo_element_class.get()), jo_ar.get() );
2416 else
2418 java_data->l = jni->NewObjectArray(
2419 1, static_cast<jclass>(jo_element_class.get()), 0 );
2421 jni.ensure_no_exception();
2423 else
2425 jni->SetObjectArrayElement(
2426 static_cast<jobjectArray>(java_data->l), 0, jo_ar.get() );
2427 jni.ensure_no_exception();
2430 else
2432 java_data->l = jo_ar.release();
2434 break;
2436 case typelib_TypeClass_INTERFACE:
2438 JLocalAutoRef jo_iface( jni );
2439 if (in_param)
2441 uno_Interface * pUnoI = *static_cast<uno_Interface * const *>(uno_data);
2442 if (0 != pUnoI)
2444 if (0 == info)
2445 info = getJniInfo()->get_type_info( jni, type );
2446 JNI_interface_type_info const * iface_info =
2447 static_cast< JNI_interface_type_info const * >( info );
2448 jo_iface.reset( map_to_java( jni, pUnoI, iface_info ) );
2451 if (out_param)
2453 if (0 == java_data->l)
2455 if (0 == info)
2456 info = getJniInfo()->get_type_info( jni, type );
2457 java_data->l =
2458 jni->NewObjectArray( 1, info->m_class, jo_iface.get() );
2459 jni.ensure_no_exception();
2461 else
2463 jni->SetObjectArrayElement(
2464 static_cast<jobjectArray>(java_data->l), 0, jo_iface.get() );
2465 jni.ensure_no_exception();
2468 else
2470 java_data->l = jo_iface.release();
2472 break;
2474 default:
2476 throw BridgeRuntimeError(
2477 "[map_to_java():" + OUString::unacquired( &type->pTypeName )
2478 + "] unsupported type!" + jni.get_stack_trace() );
2485 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */