tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / bridges / source / jni_uno / jni_data.cxx
blob15abb31f5690395cd9b4dce4226a666db9efc5d8
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"
26 #include "jni_helper.h"
28 #include <rtl/strbuf.hxx>
29 #include <uno/sequence2.h>
31 namespace jni_uno
35 static std::unique_ptr<rtl_mem> seq_allocate(
36 sal_Int32 nElements, sal_Int32 nSize )
38 std::unique_ptr< rtl_mem > seq(
39 rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
40 uno_Sequence * p = reinterpret_cast<uno_Sequence *>(seq.get());
41 p->nRefCount = 1;
42 p->nElements = nElements;
43 return seq;
47 namespace {
49 void createDefaultUnoValue(
50 JNI_context const & jni, void * uno_data,
51 typelib_TypeDescriptionReference * type,
52 JNI_type_info const * info /* maybe 0 */, bool assign)
54 switch (type->eTypeClass) {
55 case typelib_TypeClass_BOOLEAN:
56 *static_cast< sal_Bool * >(uno_data) = false;
57 break;
59 case typelib_TypeClass_BYTE:
60 *static_cast< sal_Int8 * >(uno_data) = 0;
61 break;
63 case typelib_TypeClass_SHORT:
64 *static_cast< sal_Int16 * >(uno_data) = 0;
65 break;
67 case typelib_TypeClass_UNSIGNED_SHORT:
68 *static_cast< sal_uInt16 * >(uno_data) = 0;
69 break;
71 case typelib_TypeClass_LONG:
72 *static_cast< sal_Int32 * >(uno_data) = 0;
73 break;
75 case typelib_TypeClass_UNSIGNED_LONG:
76 *static_cast< sal_uInt32 * >(uno_data) = 0;
77 break;
79 case typelib_TypeClass_HYPER:
80 *static_cast< sal_Int64 * >(uno_data) = 0;
81 break;
83 case typelib_TypeClass_UNSIGNED_HYPER:
84 *static_cast< sal_uInt64 * >(uno_data) = 0;
85 break;
87 case typelib_TypeClass_FLOAT:
88 *static_cast< float * >(uno_data) = 0;
89 break;
91 case typelib_TypeClass_DOUBLE:
92 *static_cast< double * >(uno_data) = 0;
93 break;
95 case typelib_TypeClass_CHAR:
96 *static_cast< sal_Unicode * >(uno_data) = 0;
97 break;
99 case typelib_TypeClass_STRING:
100 if (!assign) {
101 *static_cast< rtl_uString ** >(uno_data) = nullptr;
103 rtl_uString_new(static_cast< rtl_uString ** >(uno_data));
104 break;
106 case typelib_TypeClass_TYPE:
107 if (assign) {
108 typelib_typedescriptionreference_release(
109 *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
111 *static_cast< typelib_TypeDescriptionReference ** >(uno_data)
112 = *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
113 assert(
114 *static_cast< typelib_TypeDescriptionReference ** >(uno_data) != nullptr);
115 typelib_typedescriptionreference_acquire(
116 *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
117 break;
119 case typelib_TypeClass_ANY:
120 if (assign) {
121 uno_any_destruct(static_cast< uno_Any * >(uno_data), nullptr);
123 uno_any_construct(
124 static_cast< uno_Any * >(uno_data), nullptr,
125 jni.get_info()->m_XInterface_type_info->m_td.get(), nullptr);
126 break;
128 case typelib_TypeClass_SEQUENCE:
130 std::unique_ptr< rtl_mem > seq(seq_allocate(0, 0));
131 if (assign) {
132 uno_type_destructData(uno_data, type, nullptr);
134 *static_cast< uno_Sequence ** >(uno_data)
135 = reinterpret_cast< uno_Sequence * >(seq.release());
136 break;
139 case typelib_TypeClass_ENUM:
141 typelib_TypeDescription * td = nullptr;
142 TYPELIB_DANGER_GET(&td, type);
143 *static_cast< sal_Int32 * >(uno_data)
144 = (reinterpret_cast< typelib_EnumTypeDescription * >(td)->
145 nDefaultEnumValue);
146 TYPELIB_DANGER_RELEASE(td);
147 break;
150 case typelib_TypeClass_STRUCT:
152 if (info == nullptr) {
153 info = jni.get_info()->get_type_info(jni, type);
155 JNI_compound_type_info const * comp_info
156 = static_cast< JNI_compound_type_info const * >(info);
157 typelib_CompoundTypeDescription * comp_td
158 = reinterpret_cast< typelib_CompoundTypeDescription * >(
159 comp_info->m_td.get());
160 sal_Int32 nPos = 0;
161 sal_Int32 nMembers = comp_td->nMembers;
162 try {
163 if (comp_td->pBaseTypeDescription != nullptr) {
164 createDefaultUnoValue(
165 jni, uno_data,
166 comp_td->pBaseTypeDescription->aBase.pWeakRef,
167 comp_info->m_base, assign);
169 for (; nPos < nMembers; ++nPos) {
170 createDefaultUnoValue(
171 jni,
172 (static_cast< char * >(uno_data)
173 + comp_td->pMemberOffsets[nPos]),
174 comp_td->ppTypeRefs[nPos], nullptr, assign);
176 } catch (...) {
177 if (!assign) {
178 for (sal_Int32 i = 0; i < nPos; ++i) {
179 uno_type_destructData(
180 (static_cast< char * >(uno_data)
181 + comp_td->pMemberOffsets[i]),
182 comp_td->ppTypeRefs[i], nullptr);
184 if (comp_td->pBaseTypeDescription != nullptr) {
185 uno_destructData(
186 uno_data, &comp_td->pBaseTypeDescription->aBase, nullptr);
189 throw;
192 break;
194 case typelib_TypeClass_INTERFACE:
195 if (assign) {
196 uno_Interface * p = *static_cast< uno_Interface ** >(uno_data);
197 if (p != nullptr) {
198 (*p->release)(p);
201 *static_cast< uno_Interface ** >(uno_data) = nullptr;
202 break;
204 default:
205 assert(false);
206 break;
212 void Bridge::map_to_uno(
213 JNI_context const & jni,
214 void * uno_data, jvalue java_data,
215 typelib_TypeDescriptionReference * type,
216 JNI_type_info const * info /* maybe 0 */,
217 bool assign, bool out_param,
218 bool special_wrapped_integral_types ) const
220 assert(
221 !out_param ||
222 (jni->GetArrayLength( static_cast<jarray>(java_data.l) ) == 1) );
224 switch (type->eTypeClass)
226 case typelib_TypeClass_CHAR:
227 if (out_param)
229 jni->GetCharArrayRegion(
230 static_cast<jcharArray>(java_data.l), 0, 1, static_cast<jchar *>(uno_data) );
231 jni.ensure_no_exception();
233 else if (special_wrapped_integral_types)
235 *static_cast<jchar *>(uno_data) = jni->CallCharMethodA(
236 java_data.l, getJniInfo()->m_method_Character_charValue, nullptr );
237 jni.ensure_no_exception();
239 else
241 *static_cast<jchar *>(uno_data) = java_data.c;
243 break;
244 case typelib_TypeClass_BOOLEAN:
245 if (out_param)
247 jni->GetBooleanArrayRegion(
248 static_cast<jbooleanArray>(java_data.l), 0, 1, static_cast<jboolean *>(uno_data) );
249 jni.ensure_no_exception();
251 else if (special_wrapped_integral_types)
253 *static_cast<jboolean *>(uno_data) = jni->CallBooleanMethodA(
254 java_data.l, getJniInfo()->m_method_Boolean_booleanValue, nullptr );
255 jni.ensure_no_exception();
257 else
259 *static_cast<jboolean *>(uno_data) = java_data.z;
261 break;
262 case typelib_TypeClass_BYTE:
263 if (out_param)
265 jni->GetByteArrayRegion(
266 static_cast<jbyteArray>(java_data.l), 0, 1, static_cast<jbyte *>(uno_data) );
267 jni.ensure_no_exception();
269 else if (special_wrapped_integral_types)
271 *static_cast<jbyte *>(uno_data) = jni->CallByteMethodA(
272 java_data.l, getJniInfo()->m_method_Byte_byteValue, nullptr );
273 jni.ensure_no_exception();
275 else
277 *static_cast<jbyte *>(uno_data) = java_data.b;
279 break;
280 case typelib_TypeClass_SHORT:
281 case typelib_TypeClass_UNSIGNED_SHORT:
282 if (out_param)
284 jni->GetShortArrayRegion(
285 static_cast<jshortArray>(java_data.l), 0, 1, static_cast<jshort *>(uno_data) );
286 jni.ensure_no_exception();
288 else if (special_wrapped_integral_types)
290 *static_cast<jshort *>(uno_data) = jni->CallShortMethodA(
291 java_data.l, getJniInfo()->m_method_Short_shortValue, nullptr );
292 jni.ensure_no_exception();
294 else
296 *static_cast<jshort *>(uno_data) = java_data.s;
298 break;
299 case typelib_TypeClass_LONG:
300 case typelib_TypeClass_UNSIGNED_LONG:
301 if (out_param)
303 jni->GetIntArrayRegion(
304 static_cast<jintArray>(java_data.l), 0, 1, static_cast<jint *>(uno_data) );
305 jni.ensure_no_exception();
307 else if (special_wrapped_integral_types)
309 *static_cast<jint *>(uno_data) = jni->CallIntMethodA(
310 java_data.l, getJniInfo()->m_method_Integer_intValue, nullptr );
311 jni.ensure_no_exception();
313 else
315 *static_cast<jint *>(uno_data) = java_data.i;
317 break;
318 case typelib_TypeClass_HYPER:
319 case typelib_TypeClass_UNSIGNED_HYPER:
320 if (out_param)
322 jni->GetLongArrayRegion(
323 static_cast<jlongArray>(java_data.l), 0, 1, static_cast<jlong *>(uno_data) );
324 jni.ensure_no_exception();
326 else if (special_wrapped_integral_types)
328 *static_cast<jlong *>(uno_data) = jni->CallLongMethodA(
329 java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
330 jni.ensure_no_exception();
332 else
334 *static_cast<jlong *>(uno_data) = java_data.j;
336 break;
337 case typelib_TypeClass_FLOAT:
338 if (out_param)
340 jni->GetFloatArrayRegion(
341 static_cast<jfloatArray>(java_data.l), 0, 1, static_cast<jfloat *>(uno_data) );
342 jni.ensure_no_exception();
344 else if (special_wrapped_integral_types)
346 *static_cast<jfloat *>(uno_data) = jni->CallFloatMethodA(
347 java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
348 jni.ensure_no_exception();
350 else
352 *static_cast<jfloat *>(uno_data) = java_data.f;
354 break;
355 case typelib_TypeClass_DOUBLE:
356 if (out_param)
358 jni->GetDoubleArrayRegion(
359 static_cast<jdoubleArray>(java_data.l), 0, 1, static_cast<jdouble *>(uno_data) );
360 jni.ensure_no_exception();
362 else if (special_wrapped_integral_types)
364 *static_cast<jdouble *>(uno_data) = jni->CallDoubleMethodA(
365 java_data.l, getJniInfo()->m_method_Double_doubleValue, nullptr );
366 jni.ensure_no_exception();
368 else
370 *static_cast<jdouble *>(uno_data) = java_data.d;
372 break;
373 case typelib_TypeClass_STRING:
375 JLocalAutoRef jo_out_holder( jni );
376 if (out_param)
378 jo_out_holder.reset(
379 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
380 jni.ensure_no_exception();
381 java_data.l = jo_out_holder.get();
383 if (java_data.l == nullptr)
385 throw BridgeRuntimeError(
386 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
387 + "] null-ref given!" + jni.get_stack_trace() );
389 if (! assign)
390 *static_cast<rtl_uString **>(uno_data) = nullptr;
391 jstring_to_ustring(
392 jni, static_cast<rtl_uString **>(uno_data), static_cast<jstring>(java_data.l) );
393 break;
395 case typelib_TypeClass_TYPE:
397 JLocalAutoRef jo_out_holder( jni );
398 if (out_param)
400 jo_out_holder.reset(
401 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
402 jni.ensure_no_exception();
403 java_data.l = jo_out_holder.get();
405 if (java_data.l == nullptr)
407 throw BridgeRuntimeError(
408 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
409 + "] null-ref given!" + jni.get_stack_trace() );
412 // type name
413 JLocalAutoRef jo_type_name(
414 jni, jni->GetObjectField(
415 java_data.l, getJniInfo()->m_field_Type_typeName ) );
416 if (! jo_type_name.is())
418 throw BridgeRuntimeError(
419 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
420 + "] incomplete type object: no type name!"
421 + jni.get_stack_trace() );
423 OUString type_name(
424 jstring_to_oustring( jni, static_cast<jstring>(jo_type_name.get()) ) );
425 ::com::sun::star::uno::TypeDescription td( type_name );
426 if (! td.is())
428 throw BridgeRuntimeError(
429 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
430 + "] UNO type not found: " + type_name
431 + jni.get_stack_trace() );
433 typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
434 if (assign)
436 typelib_typedescriptionreference_release(
437 *static_cast<typelib_TypeDescriptionReference **>(uno_data) );
439 *static_cast<typelib_TypeDescriptionReference **>(uno_data) = td.get()->pWeakRef;
440 break;
442 case typelib_TypeClass_ANY:
444 JLocalAutoRef jo_out_holder( jni );
445 if (out_param)
447 jo_out_holder.reset(
448 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
449 jni.ensure_no_exception();
450 java_data.l = jo_out_holder.get();
453 uno_Any * pAny = static_cast<uno_Any *>(uno_data);
454 if (java_data.l == nullptr) // null-ref maps to XInterface null-ref
456 if (assign)
457 uno_any_destruct( pAny, nullptr );
458 uno_any_construct(
459 pAny, nullptr, getJniInfo()->m_XInterface_type_info->m_td.get(), nullptr );
460 break;
463 JLocalAutoRef jo_type( jni );
464 JLocalAutoRef jo_wrapped_holder( jni );
466 if (jni->IsInstanceOf( java_data.l, getJniInfo()->m_class_Any ))
468 // boxed any
469 jo_type.reset( jni->GetObjectField(
470 java_data.l, getJniInfo()->m_field_Any_type ) );
471 if (! jo_type.is())
473 throw BridgeRuntimeError(
474 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
475 + "] no type set at com.sun.star.uno.Any!"
476 + jni.get_stack_trace() );
478 // wrapped value
479 jo_wrapped_holder.reset(
480 jni->GetObjectField(
481 java_data.l, getJniInfo()->m_field_Any_object ) );
482 java_data.l = jo_wrapped_holder.get();
484 else
486 // create type out of class
487 JLocalAutoRef jo_class( jni, jni->GetObjectClass( java_data.l ) );
488 jo_type.reset( create_type( jni, static_cast<jclass>(jo_class.get()) ) );
491 // get type name
492 JLocalAutoRef jo_type_name(
493 jni, jni->GetObjectField(
494 jo_type.get(), getJniInfo()->m_field_Type_typeName ) );
495 jni.ensure_no_exception();
496 OUString type_name(
497 jstring_to_oustring( jni, static_cast<jstring>(jo_type_name.get()) ) );
499 ::com::sun::star::uno::TypeDescription value_td( type_name );
500 if (! value_td.is())
502 throw BridgeRuntimeError(
503 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
504 + "] UNO type not found: " + type_name
505 + jni.get_stack_trace() );
507 typelib_TypeClass type_class = value_td.get()->eTypeClass;
509 if (assign)
511 uno_any_destruct( pAny, nullptr );
515 switch (type_class)
517 case typelib_TypeClass_VOID:
518 pAny->pData = &pAny->pReserved;
519 break;
520 case typelib_TypeClass_CHAR:
521 pAny->pData = &pAny->pReserved;
522 *static_cast<jchar *>(pAny->pData) = jni->CallCharMethodA(
523 java_data.l, getJniInfo()->m_method_Character_charValue, nullptr );
524 jni.ensure_no_exception();
525 break;
526 case typelib_TypeClass_BOOLEAN:
527 pAny->pData = &pAny->pReserved;
528 *static_cast<jboolean *>(pAny->pData) = jni->CallBooleanMethodA(
529 java_data.l, getJniInfo()->m_method_Boolean_booleanValue, nullptr );
530 jni.ensure_no_exception();
531 break;
532 case typelib_TypeClass_BYTE:
533 pAny->pData = &pAny->pReserved;
534 *static_cast<jbyte *>(pAny->pData) = jni->CallByteMethodA(
535 java_data.l, getJniInfo()->m_method_Byte_byteValue, nullptr );
536 jni.ensure_no_exception();
537 break;
538 case typelib_TypeClass_SHORT:
539 case typelib_TypeClass_UNSIGNED_SHORT:
540 pAny->pData = &pAny->pReserved;
541 *static_cast<jshort *>(pAny->pData) = jni->CallShortMethodA(
542 java_data.l, getJniInfo()->m_method_Short_shortValue, nullptr );
543 jni.ensure_no_exception();
544 break;
545 case typelib_TypeClass_LONG:
546 case typelib_TypeClass_UNSIGNED_LONG:
547 pAny->pData = &pAny->pReserved;
548 *static_cast<jint *>(pAny->pData) = jni->CallIntMethodA(
549 java_data.l, getJniInfo()->m_method_Integer_intValue, nullptr );
550 jni.ensure_no_exception();
551 break;
552 case typelib_TypeClass_HYPER:
553 case typelib_TypeClass_UNSIGNED_HYPER:
554 if (sizeof (sal_Int64) <= sizeof (void *))
556 pAny->pData = &pAny->pReserved;
557 *static_cast<jlong *>(pAny->pData) = jni->CallLongMethodA(
558 java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
559 jni.ensure_no_exception();
561 else
563 std::unique_ptr< rtl_mem > mem(
564 rtl_mem::allocate( sizeof (sal_Int64) ) );
565 *reinterpret_cast<jlong *>(mem.get()) = jni->CallLongMethodA(
566 java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
567 jni.ensure_no_exception();
568 pAny->pData = mem.release();
570 break;
571 case typelib_TypeClass_FLOAT:
572 if (sizeof (float) <= sizeof (void *))
574 pAny->pData = &pAny->pReserved;
575 *static_cast<jfloat *>(pAny->pData) = jni->CallFloatMethodA(
576 java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
577 jni.ensure_no_exception();
579 else
581 std::unique_ptr< rtl_mem > mem(
582 rtl_mem::allocate( sizeof (float) ) );
583 *reinterpret_cast<jfloat *>(mem.get()) = jni->CallFloatMethodA(
584 java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
585 jni.ensure_no_exception();
586 pAny->pData = mem.release();
588 break;
589 case typelib_TypeClass_DOUBLE:
590 if (sizeof (double) <= sizeof (void *))
592 pAny->pData = &pAny->pReserved;
593 *static_cast<jdouble *>(pAny->pData) =
594 jni->CallDoubleMethodA(
595 java_data.l,
596 getJniInfo()->m_method_Double_doubleValue, nullptr );
597 jni.ensure_no_exception();
599 else
601 std::unique_ptr< rtl_mem > mem(
602 rtl_mem::allocate( sizeof (double) ) );
603 *reinterpret_cast<jdouble *>(mem.get()) =
604 jni->CallDoubleMethodA(
605 java_data.l,
606 getJniInfo()->m_method_Double_doubleValue, nullptr );
607 jni.ensure_no_exception();
608 pAny->pData = mem.release();
610 break;
611 case typelib_TypeClass_STRING:
612 // opt: anies often contain strings; copy string directly
613 pAny->pReserved = nullptr;
614 pAny->pData = &pAny->pReserved;
615 jstring_to_ustring(
616 jni, static_cast<rtl_uString **>(pAny->pData),
617 static_cast<jstring>(java_data.l) );
618 break;
619 case typelib_TypeClass_TYPE:
620 case typelib_TypeClass_ENUM:
621 case typelib_TypeClass_SEQUENCE:
622 case typelib_TypeClass_INTERFACE:
623 pAny->pData = &pAny->pReserved;
624 map_to_uno(
625 jni, pAny->pData, java_data,
626 value_td.get()->pWeakRef, nullptr,
627 false /* no assign */, false /* no out param */ );
628 break;
629 case typelib_TypeClass_STRUCT:
630 case typelib_TypeClass_EXCEPTION:
632 std::unique_ptr< rtl_mem > mem(
633 rtl_mem::allocate( value_td.get()->nSize ) );
634 map_to_uno(
635 jni, mem.get(), java_data, value_td.get()->pWeakRef, nullptr,
636 false /* no assign */, false /* no out param */ );
637 pAny->pData = mem.release();
638 break;
640 default:
642 throw BridgeRuntimeError(
643 "[map_to_uno():" + type_name
644 + "] unsupported value type of any!"
645 + jni.get_stack_trace() );
649 catch (...)
651 if (assign)
653 // restore to valid any
654 uno_any_construct( pAny, nullptr, nullptr, nullptr );
656 throw;
658 typelib_typedescriptionreference_acquire( value_td.get()->pWeakRef );
659 pAny->pType = value_td.get()->pWeakRef;
660 break;
662 case typelib_TypeClass_ENUM:
664 JLocalAutoRef jo_out_holder( jni );
665 if (out_param)
667 jo_out_holder.reset(
668 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
669 jni.ensure_no_exception();
670 java_data.l = jo_out_holder.get();
672 if (java_data.l == nullptr)
674 throw BridgeRuntimeError(
675 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
676 + "] null-ref given!" + jni.get_stack_trace() );
679 *static_cast<jint *>(uno_data) = jni->GetIntField(
680 java_data.l, getJniInfo()->m_field_Enum_m_value );
681 break;
683 case typelib_TypeClass_STRUCT:
684 case typelib_TypeClass_EXCEPTION:
686 JLocalAutoRef jo_out_holder( jni );
687 if (out_param)
689 jo_out_holder.reset(
690 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
691 jni.ensure_no_exception();
692 java_data.l = jo_out_holder.get();
694 if (java_data.l == nullptr)
696 throw BridgeRuntimeError(
697 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
698 + "] null-ref given!" + jni.get_stack_trace() );
701 if (info == nullptr)
702 info = getJniInfo()->get_type_info( jni, type );
703 JNI_compound_type_info const * comp_info =
704 static_cast< JNI_compound_type_info const * >( info );
706 typelib_CompoundTypeDescription * comp_td =
707 reinterpret_cast<typelib_CompoundTypeDescription *>(comp_info->m_td.get());
708 bool polymorphic
709 = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
710 && reinterpret_cast< typelib_StructTypeDescription * >(
711 comp_td)->pParameterizedTypes != nullptr;
713 sal_Int32 nPos = 0;
714 sal_Int32 nMembers = comp_td->nMembers;
717 if (comp_td->pBaseTypeDescription != nullptr)
719 map_to_uno(
720 jni, uno_data, java_data,
721 comp_td->pBaseTypeDescription->aBase.pWeakRef,
722 comp_info->m_base,
723 assign, false /* no out param */ );
726 for ( ; nPos < nMembers; ++nPos )
728 void * p = static_cast<char *>(uno_data) + comp_td->pMemberOffsets[ nPos ];
729 typelib_TypeDescriptionReference * member_type =
730 comp_td->ppTypeRefs[ nPos ];
731 jfieldID field_id = comp_info->m_fields[ nPos ];
732 bool parameterizedType = polymorphic
733 && reinterpret_cast< typelib_StructTypeDescription * >(
734 comp_td)->pParameterizedTypes[nPos];
735 switch (member_type->eTypeClass)
737 case typelib_TypeClass_CHAR:
738 if (parameterizedType) {
739 JLocalAutoRef jo(
740 jni, jni->GetObjectField( java_data.l, field_id ) );
741 if ( jo.get() == nullptr ) {
742 *static_cast<jchar *>(p) = 0;
743 } else {
744 jvalue val;
745 val.l = jo.get();
746 map_to_uno(
747 jni, p, val, member_type, nullptr, assign, false,
748 true );
750 } else {
751 *static_cast<jchar *>(p) = jni->GetCharField(
752 java_data.l, field_id );
754 break;
755 case typelib_TypeClass_BOOLEAN:
756 if (parameterizedType) {
757 JLocalAutoRef jo(
758 jni, jni->GetObjectField( java_data.l, field_id ) );
759 if ( jo.get() == nullptr ) {
760 *static_cast<jboolean *>(p) = false;
761 } else {
762 jvalue val;
763 val.l = jo.get();
764 map_to_uno(
765 jni, p, val, member_type, nullptr, assign, false,
766 true );
768 } else {
769 *static_cast<jboolean *>(p) = jni->GetBooleanField(
770 java_data.l, field_id );
772 break;
773 case typelib_TypeClass_BYTE:
774 if (parameterizedType) {
775 JLocalAutoRef jo(
776 jni, jni->GetObjectField( java_data.l, field_id ) );
777 if ( jo.get() == nullptr ) {
778 *static_cast<jbyte *>(p) = 0;
779 } else {
780 jvalue val;
781 val.l = jo.get();
782 map_to_uno(
783 jni, p, val, member_type, nullptr, assign, false,
784 true );
786 } else {
787 *static_cast<jbyte *>(p) = jni->GetByteField(
788 java_data.l, field_id );
790 break;
791 case typelib_TypeClass_SHORT:
792 case typelib_TypeClass_UNSIGNED_SHORT:
793 if (parameterizedType) {
794 JLocalAutoRef jo(
795 jni, jni->GetObjectField( java_data.l, field_id ) );
796 if ( jo.get() == nullptr ) {
797 *static_cast<jshort *>(p) = 0;
798 } else {
799 jvalue val;
800 val.l = jo.get();
801 map_to_uno(
802 jni, p, val, member_type, nullptr, assign, false,
803 true );
805 } else {
806 *static_cast<jshort *>(p) = jni->GetShortField(
807 java_data.l, field_id );
809 break;
810 case typelib_TypeClass_LONG:
811 case typelib_TypeClass_UNSIGNED_LONG:
812 if (parameterizedType) {
813 JLocalAutoRef jo(
814 jni, jni->GetObjectField( java_data.l, field_id ) );
815 if ( jo.get() == nullptr ) {
816 *static_cast<jint *>(p) = 0;
817 } else {
818 jvalue val;
819 val.l = jo.get();
820 map_to_uno(
821 jni, p, val, member_type, nullptr, assign, false,
822 true );
824 } else {
825 *static_cast<jint *>(p) = jni->GetIntField( java_data.l, field_id );
827 break;
828 case typelib_TypeClass_HYPER:
829 case typelib_TypeClass_UNSIGNED_HYPER:
830 if (parameterizedType) {
831 JLocalAutoRef jo(
832 jni, jni->GetObjectField( java_data.l, field_id ) );
833 if ( jo.get() == nullptr ) {
834 *static_cast<jlong *>(p) = 0;
835 } else {
836 jvalue val;
837 val.l = jo.get();
838 map_to_uno(
839 jni, p, val, member_type, nullptr, assign, false,
840 true );
842 } else {
843 *static_cast<jlong *>(p) = jni->GetLongField(
844 java_data.l, field_id );
846 break;
847 case typelib_TypeClass_FLOAT:
848 if (parameterizedType) {
849 JLocalAutoRef jo(
850 jni, jni->GetObjectField( java_data.l, field_id ) );
851 if ( jo.get() == nullptr ) {
852 *static_cast<jfloat *>(p) = 0;
853 } else {
854 jvalue val;
855 val.l = jo.get();
856 map_to_uno(
857 jni, p, val, member_type, nullptr, assign, false,
858 true );
860 } else {
861 *static_cast<jfloat *>(p) = jni->GetFloatField(
862 java_data.l, field_id );
864 break;
865 case typelib_TypeClass_DOUBLE:
866 if (parameterizedType) {
867 JLocalAutoRef jo(
868 jni, jni->GetObjectField( java_data.l, field_id ) );
869 if ( jo.get() == nullptr ) {
870 *static_cast<jdouble *>(p) = 0;
871 } else {
872 jvalue val;
873 val.l = jo.get();
874 map_to_uno(
875 jni, p, val, member_type, nullptr, assign, false,
876 true );
878 } else {
879 *static_cast<jdouble *>(p) = jni->GetDoubleField(
880 java_data.l, field_id );
882 break;
883 default:
885 JLocalAutoRef jo_field( jni );
886 bool checkNull;
887 if (field_id == nullptr)
889 // special for Message: call Throwable.getMessage()
890 assert(
891 type_equals(
892 type,
893 getJniInfo()->m_Exception_type.getTypeLibType() )
894 || type_equals(
895 type,
896 getJniInfo()->m_RuntimeException_type.
897 getTypeLibType() ) );
898 assert( nPos == 0 ); // first member
899 // call getMessage()
900 jo_field.reset(
901 jni->CallObjectMethodA(
902 java_data.l,
903 getJniInfo()->m_method_Throwable_getMessage, nullptr )
905 jni.ensure_no_exception();
906 checkNull = true;
908 else
910 jo_field.reset(
911 jni->GetObjectField( java_data.l, field_id ) );
912 checkNull = parameterizedType;
914 if (checkNull && !jo_field.is()) {
915 createDefaultUnoValue(jni, p, member_type, nullptr, assign);
916 } else {
917 jvalue val;
918 val.l = jo_field.get();
919 map_to_uno(
920 jni, p, val, member_type, nullptr,
921 assign, false /* no out param */ );
923 break;
928 catch (...)
930 if (! assign)
932 // cleanup
933 for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
935 void * p =
936 static_cast<char *>(uno_data) + comp_td->pMemberOffsets[ nCleanup ];
937 uno_type_destructData(
938 p, comp_td->ppTypeRefs[ nCleanup ], nullptr );
940 if (comp_td->pBaseTypeDescription != nullptr)
942 uno_destructData(
943 uno_data, &comp_td->pBaseTypeDescription->aBase, nullptr );
946 throw;
948 break;
950 case typelib_TypeClass_SEQUENCE:
952 JLocalAutoRef jo_out_holder( jni );
953 if (out_param)
955 jo_out_holder.reset(
956 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
957 jni.ensure_no_exception();
958 java_data.l = jo_out_holder.get();
960 if (java_data.l == nullptr)
962 throw BridgeRuntimeError(
963 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
964 + "] null-ref given!" + jni.get_stack_trace() );
967 TypeDescr td( type );
968 typelib_TypeDescriptionReference * element_type =
969 reinterpret_cast<typelib_IndirectTypeDescription *>(td.get())->pType;
971 std::unique_ptr< rtl_mem > seq;
972 sal_Int32 nElements = jni->GetArrayLength( static_cast<jarray>(java_data.l) );
974 switch (element_type->eTypeClass)
976 case typelib_TypeClass_CHAR:
977 seq = seq_allocate( nElements, sizeof (sal_Unicode) );
978 jni->GetCharArrayRegion(
979 static_cast<jcharArray>(java_data.l), 0, nElements,
980 reinterpret_cast<jchar *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
981 jni.ensure_no_exception();
982 break;
983 case typelib_TypeClass_BOOLEAN:
984 seq = seq_allocate( nElements, sizeof (sal_Bool) );
985 jni->GetBooleanArrayRegion(
986 static_cast<jbooleanArray>(java_data.l), 0, nElements,
987 reinterpret_cast<jboolean *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
988 jni.ensure_no_exception();
989 break;
990 case typelib_TypeClass_BYTE:
991 seq = seq_allocate( nElements, sizeof (sal_Int8) );
992 jni->GetByteArrayRegion(
993 static_cast<jbyteArray>(java_data.l), 0, nElements,
994 reinterpret_cast<jbyte *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
995 jni.ensure_no_exception();
996 break;
997 case typelib_TypeClass_SHORT:
998 case typelib_TypeClass_UNSIGNED_SHORT:
999 seq = seq_allocate( nElements, sizeof (sal_Int16) );
1000 jni->GetShortArrayRegion(
1001 static_cast<jshortArray>(java_data.l), 0, nElements,
1002 reinterpret_cast<jshort *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1003 jni.ensure_no_exception();
1004 break;
1005 case typelib_TypeClass_LONG:
1006 case typelib_TypeClass_UNSIGNED_LONG:
1007 seq = seq_allocate( nElements, sizeof (sal_Int32) );
1008 jni->GetIntArrayRegion(
1009 static_cast<jintArray>(java_data.l), 0, nElements,
1010 reinterpret_cast<jint *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1011 jni.ensure_no_exception();
1012 break;
1013 case typelib_TypeClass_HYPER:
1014 case typelib_TypeClass_UNSIGNED_HYPER:
1015 seq = seq_allocate( nElements, sizeof (sal_Int64) );
1016 jni->GetLongArrayRegion(
1017 static_cast<jlongArray>(java_data.l), 0, nElements,
1018 reinterpret_cast<jlong *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1019 jni.ensure_no_exception();
1020 break;
1021 case typelib_TypeClass_FLOAT:
1022 seq = seq_allocate( nElements, sizeof (float) );
1023 jni->GetFloatArrayRegion(
1024 static_cast<jfloatArray>(java_data.l), 0, nElements,
1025 reinterpret_cast<jfloat *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1026 jni.ensure_no_exception();
1027 break;
1028 case typelib_TypeClass_DOUBLE:
1029 seq = seq_allocate( nElements, sizeof (double) );
1030 jni->GetDoubleArrayRegion(
1031 static_cast<jdoubleArray>(java_data.l), 0, nElements,
1032 reinterpret_cast<jdouble *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1033 jni.ensure_no_exception();
1034 break;
1035 case typelib_TypeClass_STRING:
1036 case typelib_TypeClass_TYPE:
1037 case typelib_TypeClass_ANY:
1038 case typelib_TypeClass_ENUM:
1039 case typelib_TypeClass_STRUCT:
1040 case typelib_TypeClass_EXCEPTION:
1041 case typelib_TypeClass_SEQUENCE:
1042 case typelib_TypeClass_INTERFACE:
1044 TypeDescr element_td( element_type );
1045 seq = seq_allocate( nElements, element_td.get()->nSize );
1047 JNI_type_info const * element_info;
1048 if (element_type->eTypeClass == typelib_TypeClass_STRUCT ||
1049 element_type->eTypeClass == typelib_TypeClass_EXCEPTION ||
1050 element_type->eTypeClass == typelib_TypeClass_INTERFACE)
1052 element_info =
1053 getJniInfo()->get_type_info( jni, element_td.get() );
1055 else
1057 element_info = nullptr;
1060 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1064 JLocalAutoRef jo(
1065 jni, jni->GetObjectArrayElement(
1066 static_cast<jobjectArray>(java_data.l), nPos ) );
1067 jni.ensure_no_exception();
1068 jvalue val;
1069 val.l = jo.get();
1070 void * p =
1071 reinterpret_cast<uno_Sequence *>(seq.get())->elements +
1072 (nPos * element_td.get()->nSize);
1073 map_to_uno(
1074 jni, p, val, element_td.get()->pWeakRef, element_info,
1075 false /* no assign */, false /* no out param */ );
1077 catch (...)
1079 // cleanup
1080 for ( sal_Int32 nCleanPos = 0;
1081 nCleanPos < nPos; ++nCleanPos )
1083 void * p =
1084 reinterpret_cast<uno_Sequence *>(seq.get())->elements +
1085 (nCleanPos * element_td.get()->nSize);
1086 uno_destructData( p, element_td.get(), nullptr );
1088 throw;
1091 break;
1093 default:
1095 throw BridgeRuntimeError(
1096 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
1097 + "] unsupported sequence element type: "
1098 + OUString::unacquired( &element_type->pTypeName )
1099 + jni.get_stack_trace() );
1103 if (assign)
1104 uno_destructData( uno_data, td.get(), nullptr );
1105 *static_cast<uno_Sequence **>(uno_data) = reinterpret_cast<uno_Sequence *>(seq.release());
1106 break;
1108 case typelib_TypeClass_INTERFACE:
1110 JLocalAutoRef jo_out_holder( jni );
1111 if (out_param)
1113 jo_out_holder.reset(
1114 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
1115 jni.ensure_no_exception();
1116 java_data.l = jo_out_holder.get();
1119 if (java_data.l == nullptr) // null-ref
1121 if (assign)
1123 uno_Interface * p = *static_cast<uno_Interface **>(uno_data);
1124 if (p != nullptr)
1125 (*p->release)( p );
1127 *static_cast<uno_Interface **>(uno_data) = nullptr;
1129 else
1131 if (info == nullptr)
1132 info = getJniInfo()->get_type_info( jni, type );
1133 JNI_interface_type_info const * iface_info =
1134 static_cast< JNI_interface_type_info const * >( info );
1135 uno_Interface * pUnoI = map_to_uno( jni, java_data.l, iface_info );
1136 if (assign)
1138 uno_Interface * p = *static_cast<uno_Interface **>(uno_data);
1139 if (p != nullptr)
1140 (*p->release)( p );
1142 *static_cast<uno_Interface **>(uno_data) = pUnoI;
1144 break;
1146 default:
1148 throw BridgeRuntimeError(
1149 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
1150 + "] unsupported type!" + jni.get_stack_trace() );
1156 void Bridge::map_to_java(
1157 JNI_context const & jni,
1158 jvalue * java_data, void const * uno_data,
1159 typelib_TypeDescriptionReference * type,
1160 JNI_type_info const * info /* maybe 0 */,
1161 bool in_param, bool out_param,
1162 bool special_wrapped_integral_types ) const
1164 // 4th param of Set*ArrayRegion changed from pointer to non-const to pointer
1165 // to const between <http://docs.oracle.com/javase/6/docs/technotes/guides/
1166 // jni/spec/functions.html#wp22933> and <http://docs.oracle.com/javase/7/
1167 // docs/technotes/guides/jni/spec/functions.html#wp22933>; work around that
1168 // difference in a way that doesn't trigger loplugin:redundantcast:
1169 void * data = const_cast<void *>(uno_data);
1171 switch (type->eTypeClass)
1173 case typelib_TypeClass_CHAR:
1174 if (out_param)
1176 if (java_data->l == nullptr)
1178 JLocalAutoRef jo_ar( jni, jni->NewCharArray( 1 ) );
1179 jni.ensure_no_exception();
1180 if (in_param)
1182 jni->SetCharArrayRegion(
1183 static_cast<jcharArray>(jo_ar.get()), 0, 1, static_cast<jchar *>(data) );
1184 jni.ensure_no_exception();
1186 java_data->l = jo_ar.release();
1188 else
1190 if (in_param)
1192 jni->SetCharArrayRegion(
1193 static_cast<jcharArray>(java_data->l), 0, 1, static_cast<jchar *>(data) );
1194 jni.ensure_no_exception();
1198 else if (special_wrapped_integral_types)
1200 jvalue arg;
1201 arg.c = *static_cast<jchar const *>(uno_data);
1202 java_data->l = jni->NewObjectA(
1203 getJniInfo()->m_class_Character,
1204 getJniInfo()->m_ctor_Character_with_char, &arg );
1205 jni.ensure_no_exception();
1207 else
1209 java_data->c = *static_cast<jchar const *>(uno_data);
1211 break;
1212 case typelib_TypeClass_BOOLEAN:
1213 if (out_param)
1215 if (java_data->l == nullptr)
1217 JLocalAutoRef jo_ar( jni, jni->NewBooleanArray( 1 ) );
1218 jni.ensure_no_exception();
1219 if (in_param)
1221 jni->SetBooleanArrayRegion(
1222 static_cast<jbooleanArray>(jo_ar.get()),
1223 0, 1, static_cast<jboolean *>(data) );
1224 jni.ensure_no_exception();
1226 java_data->l = jo_ar.release();
1228 else
1230 if (in_param)
1232 jni->SetBooleanArrayRegion(
1233 static_cast<jbooleanArray>(java_data->l),
1234 0, 1, static_cast<jboolean *>(data) );
1235 jni.ensure_no_exception();
1239 else if (special_wrapped_integral_types)
1241 jvalue arg;
1242 arg.z = *static_cast<jboolean const *>(uno_data);
1243 java_data->l = jni->NewObjectA(
1244 getJniInfo()->m_class_Boolean,
1245 getJniInfo()->m_ctor_Boolean_with_boolean, &arg );
1246 jni.ensure_no_exception();
1248 else
1250 java_data->z = *static_cast<jboolean const *>(uno_data);
1252 break;
1253 case typelib_TypeClass_BYTE:
1254 if (out_param)
1256 if (java_data->l == nullptr)
1258 JLocalAutoRef jo_ar( jni, jni->NewByteArray( 1 ) );
1259 jni.ensure_no_exception();
1260 if (in_param)
1262 jni->SetByteArrayRegion(
1263 static_cast<jbyteArray>(jo_ar.get()), 0, 1, static_cast<jbyte *>(data) );
1264 jni.ensure_no_exception();
1266 java_data->l = jo_ar.release();
1268 else
1270 if (in_param)
1272 jni->SetByteArrayRegion(
1273 static_cast<jbyteArray>(java_data->l), 0, 1, static_cast<jbyte *>(data) );
1274 jni.ensure_no_exception();
1278 else if (special_wrapped_integral_types)
1280 jvalue arg;
1281 arg.b = *static_cast<jbyte const *>(uno_data);
1282 java_data->l = jni->NewObjectA(
1283 getJniInfo()->m_class_Byte,
1284 getJniInfo()->m_ctor_Byte_with_byte, &arg );
1285 jni.ensure_no_exception();
1287 else
1289 java_data->b = *static_cast<jbyte const *>(uno_data);
1291 break;
1292 case typelib_TypeClass_SHORT:
1293 case typelib_TypeClass_UNSIGNED_SHORT:
1294 if (out_param)
1296 if (java_data->l == nullptr)
1298 JLocalAutoRef jo_ar( jni, jni->NewShortArray( 1 ) );
1299 jni.ensure_no_exception();
1300 if (in_param)
1302 jni->SetShortArrayRegion(
1303 static_cast<jshortArray>(jo_ar.get()), 0, 1, static_cast<jshort *>(data) );
1304 jni.ensure_no_exception();
1306 java_data->l = jo_ar.release();
1308 else
1310 if (in_param)
1312 jni->SetShortArrayRegion(
1313 static_cast<jshortArray>(java_data->l), 0, 1, static_cast<jshort *>(data) );
1314 jni.ensure_no_exception();
1318 else if (special_wrapped_integral_types)
1320 jvalue arg;
1321 arg.s = *static_cast<jshort const *>(uno_data);
1322 java_data->l = jni->NewObjectA(
1323 getJniInfo()->m_class_Short,
1324 getJniInfo()->m_ctor_Short_with_short, &arg );
1325 jni.ensure_no_exception();
1327 else
1329 java_data->s = *static_cast<jshort const *>(uno_data);
1331 break;
1332 case typelib_TypeClass_LONG:
1333 case typelib_TypeClass_UNSIGNED_LONG:
1334 if (out_param)
1336 if (java_data->l == nullptr)
1338 JLocalAutoRef jo_ar( jni, jni->NewIntArray( 1 ) );
1339 jni.ensure_no_exception();
1340 if (in_param)
1342 jni->SetIntArrayRegion(
1343 static_cast<jintArray>(jo_ar.get()), 0, 1, static_cast<jint *>(data) );
1344 jni.ensure_no_exception();
1346 java_data->l = jo_ar.release();
1348 else
1350 if (in_param)
1352 jni->SetIntArrayRegion(
1353 static_cast<jintArray>(java_data->l), 0, 1, static_cast<jint *>(data) );
1354 jni.ensure_no_exception();
1358 else if (special_wrapped_integral_types)
1360 jvalue arg;
1361 arg.i = *static_cast<jint const *>(uno_data);
1362 java_data->l = jni->NewObjectA(
1363 getJniInfo()->m_class_Integer,
1364 getJniInfo()->m_ctor_Integer_with_int, &arg );
1365 jni.ensure_no_exception();
1367 else
1369 java_data->i = *static_cast<jint const *>(uno_data);
1371 break;
1372 case typelib_TypeClass_HYPER:
1373 case typelib_TypeClass_UNSIGNED_HYPER:
1374 if (out_param)
1376 if (java_data->l == nullptr)
1378 JLocalAutoRef jo_ar( jni, jni->NewLongArray( 1 ) );
1379 jni.ensure_no_exception();
1380 if (in_param)
1382 jni->SetLongArrayRegion(
1383 static_cast<jlongArray>(jo_ar.get()), 0, 1, static_cast<jlong *>(data) );
1384 jni.ensure_no_exception();
1386 java_data->l = jo_ar.release();
1388 else
1390 if (in_param)
1392 jni->SetLongArrayRegion(
1393 static_cast<jlongArray>(java_data->l), 0, 1, static_cast<jlong *>(data) );
1394 jni.ensure_no_exception();
1398 else if (special_wrapped_integral_types)
1400 jvalue arg;
1401 arg.j = *static_cast<jlong const *>(uno_data);
1402 java_data->l = jni->NewObjectA(
1403 getJniInfo()->m_class_Long,
1404 getJniInfo()->m_ctor_Long_with_long, &arg );
1405 jni.ensure_no_exception();
1407 else
1409 java_data->j = *static_cast<jlong const *>(uno_data);
1411 break;
1412 case typelib_TypeClass_FLOAT:
1413 if (out_param)
1415 if (java_data->l == nullptr)
1417 JLocalAutoRef jo_ar( jni, jni->NewFloatArray( 1 ) );
1418 jni.ensure_no_exception();
1419 if (in_param)
1421 jni->SetFloatArrayRegion(
1422 static_cast<jfloatArray>(jo_ar.get()), 0, 1, static_cast<jfloat *>(data) );
1423 jni.ensure_no_exception();
1425 java_data->l = jo_ar.release();
1427 else
1429 if (in_param)
1431 jni->SetFloatArrayRegion(
1432 static_cast<jfloatArray>(java_data->l), 0, 1, static_cast<jfloat *>(data) );
1433 jni.ensure_no_exception();
1437 else if (special_wrapped_integral_types)
1439 jvalue arg;
1440 arg.f = *static_cast<jfloat const *>(uno_data);
1441 java_data->l = jni->NewObjectA(
1442 getJniInfo()->m_class_Float,
1443 getJniInfo()->m_ctor_Float_with_float, &arg );
1444 jni.ensure_no_exception();
1446 else
1448 java_data->f = *static_cast<jfloat const *>(uno_data);
1450 break;
1451 case typelib_TypeClass_DOUBLE:
1452 if (out_param)
1454 if (java_data->l == nullptr)
1456 JLocalAutoRef jo_ar( jni, jni->NewDoubleArray( 1 ) );
1457 jni.ensure_no_exception();
1458 if (in_param)
1460 jni->SetDoubleArrayRegion(
1461 static_cast<jdoubleArray>(jo_ar.get()),
1462 0, 1, static_cast<jdouble *>(data) );
1463 jni.ensure_no_exception();
1465 java_data->l = jo_ar.release();
1467 else
1469 if (in_param)
1471 jni->SetDoubleArrayRegion(
1472 static_cast<jdoubleArray>(java_data->l),
1473 0, 1, static_cast<jdouble *>(data) );
1474 jni.ensure_no_exception();
1478 else if (special_wrapped_integral_types)
1480 jvalue arg;
1481 arg.d = *static_cast<double const *>(uno_data);
1482 java_data->l = jni->NewObjectA(
1483 getJniInfo()->m_class_Double,
1484 getJniInfo()->m_ctor_Double_with_double, &arg );
1485 jni.ensure_no_exception();
1487 else
1489 java_data->d = *static_cast<jdouble const *>(uno_data);
1491 break;
1492 case typelib_TypeClass_STRING:
1494 if (out_param)
1496 JLocalAutoRef jo_in( jni );
1497 if (in_param)
1499 jo_in.reset(
1500 ustring_to_jstring(
1501 jni, *static_cast<rtl_uString * const *>(uno_data) ) );
1503 if (java_data->l == nullptr)
1505 java_data->l = jni->NewObjectArray(
1506 1, getJniInfo()->m_class_String, jo_in.get() );
1507 jni.ensure_no_exception();
1509 else
1511 jni->SetObjectArrayElement(
1512 static_cast<jobjectArray>(java_data->l), 0, jo_in.get() );
1513 jni.ensure_no_exception();
1516 else
1518 assert( in_param );
1519 java_data->l =
1520 ustring_to_jstring( jni, *static_cast<rtl_uString * const *>(uno_data) );
1522 break;
1524 case typelib_TypeClass_TYPE:
1526 if (out_param)
1528 JLocalAutoRef jo_in( jni );
1529 if (in_param)
1531 jo_in.reset(
1532 create_type(
1533 jni,
1534 *static_cast<typelib_TypeDescriptionReference * const *>(uno_data) )
1537 if (java_data->l == nullptr)
1539 java_data->l = jni->NewObjectArray(
1540 1, getJniInfo()->m_class_Type, jo_in.get() );
1541 jni.ensure_no_exception();
1543 else
1545 jni->SetObjectArrayElement(
1546 static_cast<jobjectArray>(java_data->l), 0, jo_in.get() );
1547 jni.ensure_no_exception();
1550 else
1552 assert( in_param );
1553 java_data->l =
1554 create_type(
1555 jni,
1556 *static_cast<typelib_TypeDescriptionReference * const *>(uno_data) );
1558 break;
1560 case typelib_TypeClass_ANY:
1562 JLocalAutoRef jo_any( jni );
1563 if (in_param)
1565 uno_Any const * pAny = static_cast<uno_Any const *>(uno_data);
1566 switch (pAny->pType->eTypeClass)
1568 case typelib_TypeClass_VOID:
1569 jo_any.reset(
1570 jni->NewLocalRef( getJniInfo()->m_object_Any_VOID ) );
1571 break;
1572 case typelib_TypeClass_UNSIGNED_SHORT:
1574 jvalue args[ 2 ];
1575 args[ 0 ].s = *static_cast<jshort const *>(pAny->pData);
1576 JLocalAutoRef jo_val(
1577 jni, jni->NewObjectA(
1578 getJniInfo()->m_class_Short,
1579 getJniInfo()->m_ctor_Short_with_short, args ) );
1580 jni.ensure_no_exception();
1581 // box up in com.sun.star.uno.Any
1582 args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_SHORT;
1583 args[ 1 ].l = jo_val.get();
1584 jo_any.reset(
1585 jni->NewObjectA(
1586 getJniInfo()->m_class_Any,
1587 getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1588 jni.ensure_no_exception();
1589 break;
1591 case typelib_TypeClass_UNSIGNED_LONG:
1593 jvalue args[ 2 ];
1594 args[ 0 ].i = *static_cast<jint const *>(pAny->pData);
1595 JLocalAutoRef jo_val(
1596 jni, jni->NewObjectA(
1597 getJniInfo()->m_class_Integer,
1598 getJniInfo()->m_ctor_Integer_with_int, args ) );
1599 jni.ensure_no_exception();
1600 // box up in com.sun.star.uno.Any
1601 args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_LONG;
1602 args[ 1 ].l = jo_val.get();
1603 jo_any.reset(
1604 jni->NewObjectA(
1605 getJniInfo()->m_class_Any,
1606 getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1607 jni.ensure_no_exception();
1608 break;
1610 case typelib_TypeClass_UNSIGNED_HYPER:
1612 jvalue args[ 2 ];
1613 args[ 0 ].j = *static_cast<jlong const *>(pAny->pData);
1614 JLocalAutoRef jo_val(
1615 jni, jni->NewObjectA(
1616 getJniInfo()->m_class_Long,
1617 getJniInfo()->m_ctor_Long_with_long, args ) );
1618 jni.ensure_no_exception();
1619 // box up in com.sun.star.uno.Any
1620 args[ 0 ].l = getJniInfo()->m_object_Type_UNSIGNED_HYPER;
1621 args[ 1 ].l = jo_val.get();
1622 jo_any.reset(
1623 jni->NewObjectA(
1624 getJniInfo()->m_class_Any,
1625 getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1626 jni.ensure_no_exception();
1627 break;
1629 case typelib_TypeClass_STRING: // opt strings
1630 jo_any.reset( ustring_to_jstring(
1631 jni, static_cast<rtl_uString *>(pAny->pReserved) ) );
1632 break;
1633 case typelib_TypeClass_SEQUENCE:
1635 jvalue java_data2;
1636 // prefetch sequence td
1637 TypeDescr seq_td( pAny->pType );
1638 map_to_java(
1639 jni, &java_data2, pAny->pData, seq_td.get()->pWeakRef, nullptr,
1640 true /* in */, false /* no out */,
1641 true /* create integral wrappers */ );
1642 jo_any.reset( java_data2.l );
1644 // determine inner element type
1645 ::com::sun::star::uno::Type element_type(
1646 reinterpret_cast<typelib_IndirectTypeDescription *>(seq_td.get())->pType );
1647 while (element_type.getTypeLibType()->eTypeClass ==
1648 typelib_TypeClass_SEQUENCE)
1650 TypeDescr element_td( element_type.getTypeLibType() );
1651 typelib_typedescriptionreference_assign(
1652 reinterpret_cast< typelib_TypeDescriptionReference ** >(
1653 &element_type ),
1654 reinterpret_cast<typelib_IndirectTypeDescription *>(element_td.get())
1655 ->pType );
1657 // box up only if unsigned element type
1658 switch (element_type.getTypeLibType()->eTypeClass)
1660 case typelib_TypeClass_UNSIGNED_SHORT:
1661 case typelib_TypeClass_UNSIGNED_LONG:
1662 case typelib_TypeClass_UNSIGNED_HYPER:
1664 jvalue args[ 2 ];
1665 JLocalAutoRef jo_type(
1666 jni, create_type( jni, seq_td.get()->pWeakRef ) );
1667 args[ 0 ].l = jo_type.get();
1668 args[ 1 ].l = jo_any.get();
1669 jo_any.reset(
1670 jni->NewObjectA(
1671 getJniInfo()->m_class_Any,
1672 getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1673 jni.ensure_no_exception();
1674 break;
1676 default:
1677 break;
1679 break;
1681 case typelib_TypeClass_INTERFACE:
1683 uno_Interface * pUnoI = static_cast<uno_Interface *>(pAny->pReserved);
1684 if (is_XInterface( pAny->pType ))
1686 if (pUnoI != nullptr)
1688 jo_any.reset(
1689 map_to_java(
1690 jni, pUnoI,
1691 getJniInfo()->m_XInterface_type_info ) );
1693 // else: empty XInterface ref maps to null-ref
1695 else
1697 JNI_interface_type_info const * iface_info =
1698 static_cast< JNI_interface_type_info const * >(
1699 getJniInfo()->get_type_info( jni, pAny->pType ) );
1700 if (pUnoI != nullptr)
1702 jo_any.reset( map_to_java( jni, pUnoI, iface_info ) );
1704 // box up in com.sun.star.uno.Any
1705 jvalue args[ 2 ];
1706 args[ 0 ].l = iface_info->m_type;
1707 args[ 1 ].l = jo_any.get();
1708 jo_any.reset(
1709 jni->NewObjectA(
1710 getJniInfo()->m_class_Any,
1711 getJniInfo()->m_ctor_Any_with_Type_Object, args ) );
1712 jni.ensure_no_exception();
1714 break;
1716 case typelib_TypeClass_STRUCT:
1718 // Do not lose information about type arguments of instantiated
1719 // polymorphic struct types:
1720 OUString const & name = OUString::unacquired(
1721 &pAny->pType->pTypeName);
1722 assert(!name.isEmpty());
1723 if (name[name.getLength() - 1] == '>')
1725 // Box up in com.sun.star.uno.Any:
1726 JLocalAutoRef jo_type(jni, create_type(jni, pAny->pType));
1727 jvalue java_data2;
1728 map_to_java(
1729 jni, &java_data2, pAny->pData, pAny->pType, nullptr, true,
1730 false);
1731 jo_any.reset(java_data2.l);
1732 jvalue args[2];
1733 args[0].l = jo_type.get();
1734 args[1].l = jo_any.get();
1735 jo_any.reset(
1736 jni->NewObjectA(
1737 getJniInfo()->m_class_Any,
1738 getJniInfo()->m_ctor_Any_with_Type_Object, args));
1739 jni.ensure_no_exception();
1740 break;
1742 [[fallthrough]];
1744 default:
1746 jvalue java_data2;
1747 map_to_java(
1748 jni, &java_data2, pAny->pData, pAny->pType, nullptr,
1749 true /* in */, false /* no out */,
1750 true /* create integral wrappers */ );
1751 jo_any.reset( java_data2.l );
1752 break;
1757 if (out_param)
1759 if (java_data->l == nullptr)
1761 java_data->l = jni->NewObjectArray(
1762 1, getJniInfo()->m_class_Object, jo_any.get() );
1763 jni.ensure_no_exception();
1765 else
1767 jni->SetObjectArrayElement(
1768 static_cast<jobjectArray>(java_data->l), 0, jo_any.get() );
1769 jni.ensure_no_exception();
1772 else
1774 java_data->l = jo_any.release();
1776 break;
1778 case typelib_TypeClass_ENUM:
1780 OUString const & type_name = OUString::unacquired( &type->pTypeName );
1781 OString class_name(
1782 OUStringToOString( type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
1783 JLocalAutoRef jo_enum_class(
1784 jni, find_class( jni, class_name.getStr() ) );
1786 JLocalAutoRef jo_enum( jni );
1787 if (in_param)
1789 // call static <enum_class>.fromInt( int )
1790 OString sig = "(I)L" + class_name.replace( '.', '/' ) + ";";
1791 jmethodID method_id = jni->GetStaticMethodID(
1792 static_cast<jclass>(jo_enum_class.get()), "fromInt", sig.getStr() );
1793 jni.ensure_no_exception();
1794 assert( method_id != nullptr );
1796 jvalue arg;
1797 arg.i = *static_cast<jint const *>(uno_data);
1798 jo_enum.reset(
1799 jni->CallStaticObjectMethodA(
1800 static_cast<jclass>(jo_enum_class.get()), method_id, &arg ) );
1801 jni.ensure_no_exception();
1803 if (out_param)
1805 if (java_data->l == nullptr)
1807 java_data->l = jni->NewObjectArray(
1808 1, static_cast<jclass>(jo_enum_class.get()), jo_enum.get() );
1809 jni.ensure_no_exception();
1811 else
1813 jni->SetObjectArrayElement(
1814 static_cast<jobjectArray>(java_data->l), 0, jo_enum.get() );
1815 jni.ensure_no_exception();
1818 else
1820 java_data->l = jo_enum.release();
1822 break;
1824 case typelib_TypeClass_STRUCT:
1825 case typelib_TypeClass_EXCEPTION:
1827 if (info == nullptr)
1828 info = getJniInfo()->get_type_info( jni, type );
1829 JNI_compound_type_info const * comp_info =
1830 static_cast< JNI_compound_type_info const * >( info );
1832 JLocalAutoRef jo_comp( jni );
1833 if (in_param)
1835 if (type->eTypeClass == typelib_TypeClass_EXCEPTION)
1837 JLocalAutoRef jo_message(
1838 jni, ustring_to_jstring( jni, *static_cast<rtl_uString * const *>(uno_data) ) );
1839 jvalue arg;
1840 arg.l = jo_message.get();
1841 jo_comp.reset(
1842 jni->NewObjectA(
1843 comp_info->m_class, comp_info->m_exc_ctor, &arg ) );
1844 jni.ensure_no_exception();
1846 else
1848 jo_comp.reset( jni->AllocObject( comp_info->m_class ) );
1849 jni.ensure_no_exception();
1852 for ( JNI_compound_type_info const * linfo = comp_info;
1853 linfo != nullptr;
1854 linfo = static_cast< JNI_compound_type_info const * >(
1855 linfo->m_base ) )
1857 typelib_CompoundTypeDescription * comp_td =
1858 reinterpret_cast<typelib_CompoundTypeDescription *>(linfo->m_td.get());
1859 typelib_TypeDescriptionReference ** ppMemberTypeRefs =
1860 comp_td->ppTypeRefs;
1861 sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
1862 bool polymorphic
1863 = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
1864 && reinterpret_cast< typelib_StructTypeDescription * >(
1865 comp_td)->pParameterizedTypes != nullptr;
1866 for ( sal_Int32 nPos = comp_td->nMembers; nPos--; )
1868 jfieldID field_id = linfo->m_fields[ nPos ];
1869 if (field_id != nullptr)
1871 void const * p =
1872 static_cast<char const *>(uno_data) + pMemberOffsets[ nPos ];
1873 typelib_TypeDescriptionReference * member_type =
1874 ppMemberTypeRefs[ nPos ];
1875 bool parameterizedType = polymorphic
1876 && (reinterpret_cast<
1877 typelib_StructTypeDescription * >(comp_td)->
1878 pParameterizedTypes[nPos]);
1879 switch (member_type->eTypeClass)
1881 case typelib_TypeClass_CHAR:
1882 if (parameterizedType) {
1883 jvalue arg;
1884 arg.c = *static_cast<jchar const *>(p);
1885 JLocalAutoRef jo(
1886 jni,
1887 jni->NewObjectA(
1888 getJniInfo()->m_class_Character,
1889 getJniInfo()->m_ctor_Character_with_char,
1890 &arg ) );
1891 jni.ensure_no_exception();
1892 jni->SetObjectField(
1893 jo_comp.get(), field_id, jo.get() );
1894 } else {
1895 jni->SetCharField(
1896 jo_comp.get(),
1897 field_id, *static_cast<jchar const *>(p) );
1899 break;
1900 case typelib_TypeClass_BOOLEAN:
1901 if (parameterizedType) {
1902 jvalue arg;
1903 arg.z = *static_cast<jboolean const *>(p);
1904 JLocalAutoRef jo(
1905 jni,
1906 jni->NewObjectA(
1907 getJniInfo()->m_class_Boolean,
1908 getJniInfo()->m_ctor_Boolean_with_boolean,
1909 &arg ) );
1910 jni.ensure_no_exception();
1911 jni->SetObjectField(
1912 jo_comp.get(), field_id, jo.get() );
1913 } else {
1914 jni->SetBooleanField(
1915 jo_comp.get(),
1916 field_id, *static_cast<jboolean const *>(p) );
1918 break;
1919 case typelib_TypeClass_BYTE:
1920 if (parameterizedType) {
1921 jvalue arg;
1922 arg.b = *static_cast<jbyte const *>(p);
1923 JLocalAutoRef jo(
1924 jni,
1925 jni->NewObjectA(
1926 getJniInfo()->m_class_Byte,
1927 getJniInfo()->m_ctor_Byte_with_byte,
1928 &arg ) );
1929 jni.ensure_no_exception();
1930 jni->SetObjectField(
1931 jo_comp.get(), field_id, jo.get() );
1932 } else {
1933 jni->SetByteField(
1934 jo_comp.get(),
1935 field_id, *static_cast<jbyte const *>(p) );
1937 break;
1938 case typelib_TypeClass_SHORT:
1939 case typelib_TypeClass_UNSIGNED_SHORT:
1940 if (parameterizedType) {
1941 jvalue arg;
1942 arg.s = *static_cast<jshort const *>(p);
1943 JLocalAutoRef jo(
1944 jni,
1945 jni->NewObjectA(
1946 getJniInfo()->m_class_Short,
1947 getJniInfo()->m_ctor_Short_with_short,
1948 &arg ) );
1949 jni.ensure_no_exception();
1950 jni->SetObjectField(
1951 jo_comp.get(), field_id, jo.get() );
1952 } else {
1953 jni->SetShortField(
1954 jo_comp.get(),
1955 field_id, *static_cast<jshort const *>(p) );
1957 break;
1958 case typelib_TypeClass_LONG:
1959 case typelib_TypeClass_UNSIGNED_LONG:
1960 if (parameterizedType) {
1961 jvalue arg;
1962 arg.i = *static_cast<jint const *>(p);
1963 JLocalAutoRef jo(
1964 jni,
1965 jni->NewObjectA(
1966 getJniInfo()->m_class_Integer,
1967 getJniInfo()->m_ctor_Integer_with_int,
1968 &arg ) );
1969 jni.ensure_no_exception();
1970 jni->SetObjectField(
1971 jo_comp.get(), field_id, jo.get() );
1972 } else {
1973 jni->SetIntField(
1974 jo_comp.get(),
1975 field_id, *static_cast<jint const *>(p) );
1977 break;
1978 case typelib_TypeClass_HYPER:
1979 case typelib_TypeClass_UNSIGNED_HYPER:
1980 if (parameterizedType) {
1981 jvalue arg;
1982 arg.j = *static_cast<jlong const *>(p);
1983 JLocalAutoRef jo(
1984 jni,
1985 jni->NewObjectA(
1986 getJniInfo()->m_class_Long,
1987 getJniInfo()->m_ctor_Long_with_long,
1988 &arg ) );
1989 jni.ensure_no_exception();
1990 jni->SetObjectField(
1991 jo_comp.get(), field_id, jo.get() );
1992 } else {
1993 jni->SetLongField(
1994 jo_comp.get(),
1995 field_id, *static_cast<jlong const *>(p) );
1997 break;
1998 case typelib_TypeClass_FLOAT:
1999 if (parameterizedType) {
2000 jvalue arg;
2001 arg.f = *static_cast<jfloat const *>(p);
2002 JLocalAutoRef jo(
2003 jni,
2004 jni->NewObjectA(
2005 getJniInfo()->m_class_Float,
2006 getJniInfo()->m_ctor_Float_with_float,
2007 &arg ) );
2008 jni.ensure_no_exception();
2009 jni->SetObjectField(
2010 jo_comp.get(), field_id, jo.get() );
2011 } else {
2012 jni->SetFloatField(
2013 jo_comp.get(),
2014 field_id, *static_cast<jfloat const *>(p) );
2016 break;
2017 case typelib_TypeClass_DOUBLE:
2018 if (parameterizedType) {
2019 jvalue arg;
2020 arg.d = *static_cast<jdouble const *>(p);
2021 JLocalAutoRef jo(
2022 jni,
2023 jni->NewObjectA(
2024 getJniInfo()->m_class_Double,
2025 getJniInfo()->m_ctor_Double_with_double,
2026 &arg ) );
2027 jni.ensure_no_exception();
2028 jni->SetObjectField(
2029 jo_comp.get(), field_id, jo.get() );
2030 } else {
2031 jni->SetDoubleField(
2032 jo_comp.get(),
2033 field_id, *static_cast<jdouble const *>(p) );
2035 break;
2036 case typelib_TypeClass_STRING: // string opt here
2038 JLocalAutoRef jo_string(
2039 jni, ustring_to_jstring(
2040 jni, *static_cast<rtl_uString * const *>(p) ) );
2041 jni->SetObjectField(
2042 jo_comp.get(), field_id, jo_string.get() );
2043 break;
2045 default:
2047 jvalue java_data2;
2048 map_to_java(
2049 jni, &java_data2, p, member_type, nullptr,
2050 true /* in */, false /* no out */ );
2051 JLocalAutoRef jo_obj( jni, java_data2.l );
2052 jni->SetObjectField(
2053 jo_comp.get(), field_id, jo_obj.get() );
2054 break;
2061 if (out_param)
2063 if (java_data->l == nullptr)
2065 java_data->l =
2066 jni->NewObjectArray( 1, comp_info->m_class, jo_comp.get() );
2067 jni.ensure_no_exception();
2069 else
2071 jni->SetObjectArrayElement(
2072 static_cast<jobjectArray>(java_data->l), 0, jo_comp.get() );
2073 jni.ensure_no_exception();
2076 else
2078 java_data->l = jo_comp.release();
2080 break;
2082 case typelib_TypeClass_SEQUENCE:
2084 // xxx todo: possible opt for pure out sequences
2085 JLocalAutoRef jo_ar( jni );
2087 sal_Int32 nElements;
2088 uno_Sequence * seq = nullptr;
2089 if (in_param)
2091 seq = *static_cast<uno_Sequence * const *>(uno_data);
2092 nElements = seq->nElements;
2094 else
2096 nElements = 0;
2099 TypeDescr td( type );
2100 typelib_TypeDescriptionReference * element_type =
2101 reinterpret_cast<typelib_IndirectTypeDescription *>(td.get())->pType;
2103 switch (element_type->eTypeClass)
2105 case typelib_TypeClass_CHAR:
2106 jo_ar.reset( jni->NewCharArray( nElements ) );
2107 jni.ensure_no_exception();
2108 if (0 < nElements)
2110 jni->SetCharArrayRegion(
2111 static_cast<jcharArray>(jo_ar.get()),
2112 0, nElements, reinterpret_cast<jchar *>(seq->elements) );
2113 jni.ensure_no_exception();
2115 break;
2116 case typelib_TypeClass_BOOLEAN:
2117 jo_ar.reset( jni->NewBooleanArray( nElements ) );
2118 jni.ensure_no_exception();
2119 if (0 < nElements)
2121 jni->SetBooleanArrayRegion(
2122 static_cast<jbooleanArray>(jo_ar.get()),
2123 0, nElements, reinterpret_cast<jboolean *>(seq->elements) );
2124 jni.ensure_no_exception();
2126 break;
2127 case typelib_TypeClass_BYTE:
2128 jo_ar.reset( jni->NewByteArray( nElements ) );
2129 jni.ensure_no_exception();
2130 if (0 < nElements)
2132 jni->SetByteArrayRegion(
2133 static_cast<jbyteArray>(jo_ar.get()),
2134 0, nElements, reinterpret_cast<jbyte *>(seq->elements) );
2135 jni.ensure_no_exception();
2137 break;
2138 case typelib_TypeClass_SHORT:
2139 case typelib_TypeClass_UNSIGNED_SHORT:
2140 jo_ar.reset( jni->NewShortArray( nElements ) );
2141 jni.ensure_no_exception();
2142 if (0 < nElements)
2144 jni->SetShortArrayRegion(
2145 static_cast<jshortArray>(jo_ar.get()),
2146 0, nElements, reinterpret_cast<jshort *>(seq->elements) );
2147 jni.ensure_no_exception();
2149 break;
2150 case typelib_TypeClass_LONG:
2151 case typelib_TypeClass_UNSIGNED_LONG:
2152 jo_ar.reset( jni->NewIntArray( nElements ) );
2153 jni.ensure_no_exception();
2154 if (0 < nElements)
2156 jni->SetIntArrayRegion(
2157 static_cast<jintArray>(jo_ar.get()),
2158 0, nElements, reinterpret_cast<jint *>(seq->elements) );
2159 jni.ensure_no_exception();
2161 break;
2162 case typelib_TypeClass_HYPER:
2163 case typelib_TypeClass_UNSIGNED_HYPER:
2164 jo_ar.reset( jni->NewLongArray( nElements ) );
2165 jni.ensure_no_exception();
2166 if (0 < nElements)
2168 jni->SetLongArrayRegion(
2169 static_cast<jlongArray>(jo_ar.get()),
2170 0, nElements, reinterpret_cast<jlong *>(seq->elements) );
2171 jni.ensure_no_exception();
2173 break;
2174 case typelib_TypeClass_FLOAT:
2175 jo_ar.reset( jni->NewFloatArray( nElements ) );
2176 jni.ensure_no_exception();
2177 if (0 < nElements)
2179 jni->SetFloatArrayRegion(
2180 static_cast<jfloatArray>(jo_ar.get()),
2181 0, nElements, reinterpret_cast<jfloat *>(seq->elements) );
2182 jni.ensure_no_exception();
2184 break;
2185 case typelib_TypeClass_DOUBLE:
2186 jo_ar.reset( jni->NewDoubleArray( nElements ) );
2187 jni.ensure_no_exception();
2188 if (0 < nElements)
2190 jni->SetDoubleArrayRegion(
2191 static_cast<jdoubleArray>(jo_ar.get()),
2192 0, nElements, reinterpret_cast<jdouble *>(seq->elements) );
2193 jni.ensure_no_exception();
2195 break;
2196 case typelib_TypeClass_STRING:
2197 jo_ar.reset(
2198 jni->NewObjectArray(
2199 nElements, getJniInfo()->m_class_String, nullptr ) );
2200 jni.ensure_no_exception();
2201 if (in_param)
2203 rtl_uString * const * pp =
2204 reinterpret_cast<rtl_uString * const *>(seq->elements);
2205 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2207 JLocalAutoRef jo_string(
2208 jni, ustring_to_jstring( jni, pp[ nPos ] ) );
2209 jni->SetObjectArrayElement(
2210 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_string.get() );
2211 jni.ensure_no_exception();
2214 break;
2215 case typelib_TypeClass_TYPE:
2216 jo_ar.reset(
2217 jni->NewObjectArray( nElements, getJniInfo()->m_class_Type, nullptr ) );
2218 jni.ensure_no_exception();
2219 if (in_param)
2221 typelib_TypeDescriptionReference * const * pp =
2222 reinterpret_cast<typelib_TypeDescriptionReference * const *>(seq->elements);
2223 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2225 jvalue val;
2226 map_to_java(
2227 jni, &val, &pp[ nPos ], element_type, nullptr,
2228 true /* in */, false /* no out */ );
2229 JLocalAutoRef jo_element( jni, val.l );
2230 jni->SetObjectArrayElement(
2231 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2232 jni.ensure_no_exception();
2235 break;
2236 case typelib_TypeClass_ANY:
2237 jo_ar.reset(
2238 jni->NewObjectArray(
2239 nElements, getJniInfo()->m_class_Object, nullptr ) );
2240 jni.ensure_no_exception();
2241 if (in_param)
2243 uno_Any const * p = reinterpret_cast<uno_Any const *>(seq->elements);
2244 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2246 jvalue val;
2247 map_to_java(
2248 jni, &val, &p[ nPos ], element_type, nullptr,
2249 true /* in */, false /* no out */ );
2250 JLocalAutoRef jo_element( jni, val.l );
2251 jni->SetObjectArrayElement(
2252 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2253 jni.ensure_no_exception();
2256 break;
2257 case typelib_TypeClass_ENUM:
2259 OUString const & element_type_name =
2260 OUString::unacquired( &element_type->pTypeName );
2261 OString class_name(
2262 OUStringToOString(
2263 element_type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
2264 JLocalAutoRef jo_enum_class(
2265 jni, find_class( jni, class_name.getStr() ) );
2267 jo_ar.reset(
2268 jni->NewObjectArray(
2269 nElements, static_cast<jclass>(jo_enum_class.get()), nullptr ) );
2270 jni.ensure_no_exception();
2272 if (0 < nElements)
2274 // call static <enum_class>.fromInt( int )
2275 OString sig = "(I)L" + class_name.replace( '.', '/' ) + ";";
2276 jmethodID method_id = jni->GetStaticMethodID(
2277 static_cast<jclass>(jo_enum_class.get()), "fromInt", sig.getStr() );
2278 jni.ensure_no_exception();
2279 assert( method_id != nullptr );
2281 sal_Int32 const * p = reinterpret_cast<sal_Int32 const *>(seq->elements);
2282 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2284 jvalue arg;
2285 arg.i = p[ nPos ];
2286 JLocalAutoRef jo_enum(
2287 jni, jni->CallStaticObjectMethodA(
2288 static_cast<jclass>(jo_enum_class.get()), method_id, &arg ) );
2289 jni.ensure_no_exception();
2290 jni->SetObjectArrayElement(
2291 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_enum.get() );
2292 jni.ensure_no_exception();
2295 break;
2297 case typelib_TypeClass_STRUCT:
2298 case typelib_TypeClass_EXCEPTION:
2300 JNI_type_info const * element_info =
2301 getJniInfo()->get_type_info( jni, element_type );
2303 jo_ar.reset(
2304 jni->NewObjectArray( nElements, element_info->m_class, nullptr ) );
2305 jni.ensure_no_exception();
2307 if (0 < nElements)
2309 char * p = const_cast<char *>(seq->elements);
2310 sal_Int32 nSize = element_info->m_td.get()->nSize;
2311 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2313 jvalue val;
2314 map_to_java(
2315 jni, &val, p + (nSize * nPos),
2316 element_type, element_info,
2317 true /* in */, false /* no out */ );
2318 JLocalAutoRef jo_element( jni, val.l );
2319 jni->SetObjectArrayElement(
2320 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2321 jni.ensure_no_exception();
2324 break;
2326 case typelib_TypeClass_SEQUENCE:
2328 OStringBuffer buf( 64 );
2329 JNI_info::append_sig(
2330 &buf, element_type, false /* use class XInterface */,
2331 false /* '.' instead of '/' */ );
2332 OString class_name( buf.makeStringAndClear() );
2333 JLocalAutoRef jo_seq_class(
2334 jni, find_class( jni, class_name.getStr() ) );
2336 jo_ar.reset(
2337 jni->NewObjectArray(
2338 nElements, static_cast<jclass>(jo_seq_class.get()), nullptr ) );
2339 jni.ensure_no_exception();
2341 if (0 < nElements)
2343 uno_Sequence * const * elements = reinterpret_cast<uno_Sequence * const *>(seq->elements);
2344 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2346 jvalue java_data2;
2347 map_to_java(
2348 jni, &java_data2, elements + nPos, element_type, nullptr,
2349 true /* in */, false /* no out */ );
2350 JLocalAutoRef jo_seq( jni, java_data2.l );
2351 jni->SetObjectArrayElement(
2352 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_seq.get() );
2353 jni.ensure_no_exception();
2356 break;
2358 case typelib_TypeClass_INTERFACE:
2360 JNI_interface_type_info const * iface_info =
2361 static_cast< JNI_interface_type_info const * >(
2362 getJniInfo()->get_type_info( jni, element_type ) );
2364 jo_ar.reset(
2365 jni->NewObjectArray( nElements, iface_info->m_class, nullptr ) );
2366 jni.ensure_no_exception();
2368 if (0 < nElements)
2370 uno_Interface * const * pp = reinterpret_cast<uno_Interface * const *>(seq->elements);
2371 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2373 uno_Interface * pUnoI = pp[ nPos ];
2374 if (pUnoI != nullptr)
2376 JLocalAutoRef jo_element(
2377 jni, map_to_java( jni, pUnoI, iface_info ) );
2378 jni->SetObjectArrayElement(
2379 static_cast<jobjectArray>(jo_ar.get()),
2380 nPos, jo_element.get() );
2381 jni.ensure_no_exception();
2385 break;
2387 default:
2389 throw BridgeRuntimeError(
2390 "[map_to_java():" + OUString::unacquired( &type->pTypeName )
2391 + "] unsupported element type: "
2392 + OUString::unacquired( &element_type->pTypeName )
2393 + jni.get_stack_trace() );
2397 if (out_param)
2399 if (java_data->l == nullptr)
2401 JLocalAutoRef jo_element_class(
2402 jni, jni->GetObjectClass( jo_ar.get() ) );
2403 if (in_param)
2405 java_data->l = jni->NewObjectArray(
2406 1, static_cast<jclass>(jo_element_class.get()), jo_ar.get() );
2408 else
2410 java_data->l = jni->NewObjectArray(
2411 1, static_cast<jclass>(jo_element_class.get()), nullptr );
2413 jni.ensure_no_exception();
2415 else
2417 jni->SetObjectArrayElement(
2418 static_cast<jobjectArray>(java_data->l), 0, jo_ar.get() );
2419 jni.ensure_no_exception();
2422 else
2424 java_data->l = jo_ar.release();
2426 break;
2428 case typelib_TypeClass_INTERFACE:
2430 JLocalAutoRef jo_iface( jni );
2431 if (in_param)
2433 uno_Interface * pUnoI = *static_cast<uno_Interface * const *>(uno_data);
2434 if (pUnoI != nullptr)
2436 if (info == nullptr)
2437 info = getJniInfo()->get_type_info( jni, type );
2438 JNI_interface_type_info const * iface_info =
2439 static_cast< JNI_interface_type_info const * >( info );
2440 jo_iface.reset( map_to_java( jni, pUnoI, iface_info ) );
2443 if (out_param)
2445 if (java_data->l == nullptr)
2447 if (info == nullptr)
2448 info = getJniInfo()->get_type_info( jni, type );
2449 java_data->l =
2450 jni->NewObjectArray( 1, info->m_class, jo_iface.get() );
2451 jni.ensure_no_exception();
2453 else
2455 jni->SetObjectArrayElement(
2456 static_cast<jobjectArray>(java_data->l), 0, jo_iface.get() );
2457 jni.ensure_no_exception();
2460 else
2462 java_data->l = jo_iface.release();
2464 break;
2466 default:
2468 throw BridgeRuntimeError(
2469 "[map_to_java():" + OUString::unacquired( &type->pTypeName )
2470 + "] unsupported type!" + jni.get_stack_trace() );
2477 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */