Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / bridges / source / jni_uno / jni_data.cxx
blob06e8467f7e7c7499806abd9f8d62df99a152d909
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 static std::unique_ptr<rtl_mem> seq_allocate(
35 sal_Int32 nElements, sal_Int32 nSize )
37 std::unique_ptr< rtl_mem > seq(
38 rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
39 uno_Sequence * p = reinterpret_cast<uno_Sequence *>(seq.get());
40 p->nRefCount = 1;
41 p->nElements = nElements;
42 return seq;
46 namespace {
48 void createDefaultUnoValue(
49 JNI_context const & jni, void * uno_data,
50 typelib_TypeDescriptionReference * type,
51 JNI_type_info const * info /* maybe 0 */, bool assign)
53 switch (type->eTypeClass) {
54 case typelib_TypeClass_BOOLEAN:
55 *static_cast< sal_Bool * >(uno_data) = false;
56 break;
58 case typelib_TypeClass_BYTE:
59 *static_cast< sal_Int8 * >(uno_data) = 0;
60 break;
62 case typelib_TypeClass_SHORT:
63 *static_cast< sal_Int16 * >(uno_data) = 0;
64 break;
66 case typelib_TypeClass_UNSIGNED_SHORT:
67 *static_cast< sal_uInt16 * >(uno_data) = 0;
68 break;
70 case typelib_TypeClass_LONG:
71 *static_cast< sal_Int32 * >(uno_data) = 0;
72 break;
74 case typelib_TypeClass_UNSIGNED_LONG:
75 *static_cast< sal_uInt32 * >(uno_data) = 0;
76 break;
78 case typelib_TypeClass_HYPER:
79 *static_cast< sal_Int64 * >(uno_data) = 0;
80 break;
82 case typelib_TypeClass_UNSIGNED_HYPER:
83 *static_cast< sal_uInt64 * >(uno_data) = 0;
84 break;
86 case typelib_TypeClass_FLOAT:
87 *static_cast< float * >(uno_data) = 0;
88 break;
90 case typelib_TypeClass_DOUBLE:
91 *static_cast< double * >(uno_data) = 0;
92 break;
94 case typelib_TypeClass_CHAR:
95 *static_cast< sal_Unicode * >(uno_data) = 0;
96 break;
98 case typelib_TypeClass_STRING:
99 if (!assign) {
100 *static_cast< rtl_uString ** >(uno_data) = nullptr;
102 rtl_uString_new(static_cast< rtl_uString ** >(uno_data));
103 break;
105 case typelib_TypeClass_TYPE:
106 if (assign) {
107 typelib_typedescriptionreference_release(
108 *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
110 *static_cast< typelib_TypeDescriptionReference ** >(uno_data)
111 = *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
112 assert(
113 *static_cast< typelib_TypeDescriptionReference ** >(uno_data) != nullptr);
114 typelib_typedescriptionreference_acquire(
115 *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
116 break;
118 case typelib_TypeClass_ANY:
119 if (assign) {
120 uno_any_destruct(static_cast< uno_Any * >(uno_data), nullptr);
122 uno_any_construct(
123 static_cast< uno_Any * >(uno_data), nullptr,
124 jni.get_info()->m_XInterface_type_info->m_td.get(), nullptr);
125 break;
127 case typelib_TypeClass_SEQUENCE:
129 std::unique_ptr< rtl_mem > seq(seq_allocate(0, 0));
130 if (assign) {
131 uno_type_destructData(uno_data, type, nullptr);
133 *static_cast< uno_Sequence ** >(uno_data)
134 = reinterpret_cast< uno_Sequence * >(seq.release());
135 break;
138 case typelib_TypeClass_ENUM:
140 typelib_TypeDescription * td = nullptr;
141 TYPELIB_DANGER_GET(&td, type);
142 *static_cast< sal_Int32 * >(uno_data)
143 = (reinterpret_cast< typelib_EnumTypeDescription * >(td)->
144 nDefaultEnumValue);
145 TYPELIB_DANGER_RELEASE(td);
146 break;
149 case typelib_TypeClass_STRUCT:
151 if (info == nullptr) {
152 info = jni.get_info()->get_type_info(jni, type);
154 JNI_compound_type_info const * comp_info
155 = static_cast< JNI_compound_type_info const * >(info);
156 typelib_CompoundTypeDescription * comp_td
157 = reinterpret_cast< typelib_CompoundTypeDescription * >(
158 comp_info->m_td.get());
159 sal_Int32 nPos = 0;
160 sal_Int32 nMembers = comp_td->nMembers;
161 try {
162 if (comp_td->pBaseTypeDescription != nullptr) {
163 createDefaultUnoValue(
164 jni, uno_data,
165 comp_td->pBaseTypeDescription->aBase.pWeakRef,
166 comp_info->m_base, assign);
168 for (; nPos < nMembers; ++nPos) {
169 createDefaultUnoValue(
170 jni,
171 (static_cast< char * >(uno_data)
172 + comp_td->pMemberOffsets[nPos]),
173 comp_td->ppTypeRefs[nPos], nullptr, assign);
175 } catch (...) {
176 if (!assign) {
177 for (sal_Int32 i = 0; i < nPos; ++i) {
178 uno_type_destructData(
179 (static_cast< char * >(uno_data)
180 + comp_td->pMemberOffsets[i]),
181 comp_td->ppTypeRefs[i], nullptr);
183 if (comp_td->pBaseTypeDescription != nullptr) {
184 uno_destructData(
185 uno_data, &comp_td->pBaseTypeDescription->aBase, nullptr);
188 throw;
191 break;
193 case typelib_TypeClass_INTERFACE:
194 if (assign) {
195 uno_Interface * p = *static_cast< uno_Interface ** >(uno_data);
196 if (p != nullptr) {
197 (*p->release)(p);
200 *static_cast< uno_Interface ** >(uno_data) = nullptr;
201 break;
203 default:
204 assert(false);
205 break;
211 void Bridge::map_to_uno(
212 JNI_context const & jni,
213 void * uno_data, jvalue java_data,
214 typelib_TypeDescriptionReference * type,
215 JNI_type_info const * info /* maybe 0 */,
216 bool assign, bool out_param,
217 bool special_wrapped_integral_types ) const
219 assert(
220 !out_param ||
221 (jni->GetArrayLength( static_cast<jarray>(java_data.l) ) == 1) );
223 switch (type->eTypeClass)
225 case typelib_TypeClass_CHAR:
226 if (out_param)
228 jni->GetCharArrayRegion(
229 static_cast<jcharArray>(java_data.l), 0, 1, static_cast<jchar *>(uno_data) );
230 jni.ensure_no_exception();
232 else if (special_wrapped_integral_types)
234 *static_cast<jchar *>(uno_data) = jni->CallCharMethodA(
235 java_data.l, getJniInfo()->m_method_Character_charValue, nullptr );
236 jni.ensure_no_exception();
238 else
240 *static_cast<jchar *>(uno_data) = java_data.c;
242 break;
243 case typelib_TypeClass_BOOLEAN:
244 if (out_param)
246 jni->GetBooleanArrayRegion(
247 static_cast<jbooleanArray>(java_data.l), 0, 1, static_cast<jboolean *>(uno_data) );
248 jni.ensure_no_exception();
250 else if (special_wrapped_integral_types)
252 *static_cast<jboolean *>(uno_data) = jni->CallBooleanMethodA(
253 java_data.l, getJniInfo()->m_method_Boolean_booleanValue, nullptr );
254 jni.ensure_no_exception();
256 else
258 *static_cast<jboolean *>(uno_data) = java_data.z;
260 break;
261 case typelib_TypeClass_BYTE:
262 if (out_param)
264 jni->GetByteArrayRegion(
265 static_cast<jbyteArray>(java_data.l), 0, 1, static_cast<jbyte *>(uno_data) );
266 jni.ensure_no_exception();
268 else if (special_wrapped_integral_types)
270 *static_cast<jbyte *>(uno_data) = jni->CallByteMethodA(
271 java_data.l, getJniInfo()->m_method_Byte_byteValue, nullptr );
272 jni.ensure_no_exception();
274 else
276 *static_cast<jbyte *>(uno_data) = java_data.b;
278 break;
279 case typelib_TypeClass_SHORT:
280 case typelib_TypeClass_UNSIGNED_SHORT:
281 if (out_param)
283 jni->GetShortArrayRegion(
284 static_cast<jshortArray>(java_data.l), 0, 1, static_cast<jshort *>(uno_data) );
285 jni.ensure_no_exception();
287 else if (special_wrapped_integral_types)
289 *static_cast<jshort *>(uno_data) = jni->CallShortMethodA(
290 java_data.l, getJniInfo()->m_method_Short_shortValue, nullptr );
291 jni.ensure_no_exception();
293 else
295 *static_cast<jshort *>(uno_data) = java_data.s;
297 break;
298 case typelib_TypeClass_LONG:
299 case typelib_TypeClass_UNSIGNED_LONG:
300 if (out_param)
302 jni->GetIntArrayRegion(
303 static_cast<jintArray>(java_data.l), 0, 1, static_cast<jint *>(uno_data) );
304 jni.ensure_no_exception();
306 else if (special_wrapped_integral_types)
308 *static_cast<jint *>(uno_data) = jni->CallIntMethodA(
309 java_data.l, getJniInfo()->m_method_Integer_intValue, nullptr );
310 jni.ensure_no_exception();
312 else
314 *static_cast<jint *>(uno_data) = java_data.i;
316 break;
317 case typelib_TypeClass_HYPER:
318 case typelib_TypeClass_UNSIGNED_HYPER:
319 if (out_param)
321 jni->GetLongArrayRegion(
322 static_cast<jlongArray>(java_data.l), 0, 1, static_cast<jlong *>(uno_data) );
323 jni.ensure_no_exception();
325 else if (special_wrapped_integral_types)
327 *static_cast<jlong *>(uno_data) = jni->CallLongMethodA(
328 java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
329 jni.ensure_no_exception();
331 else
333 *static_cast<jlong *>(uno_data) = java_data.j;
335 break;
336 case typelib_TypeClass_FLOAT:
337 if (out_param)
339 jni->GetFloatArrayRegion(
340 static_cast<jfloatArray>(java_data.l), 0, 1, static_cast<jfloat *>(uno_data) );
341 jni.ensure_no_exception();
343 else if (special_wrapped_integral_types)
345 *static_cast<jfloat *>(uno_data) = jni->CallFloatMethodA(
346 java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
347 jni.ensure_no_exception();
349 else
351 *static_cast<jfloat *>(uno_data) = java_data.f;
353 break;
354 case typelib_TypeClass_DOUBLE:
355 if (out_param)
357 jni->GetDoubleArrayRegion(
358 static_cast<jdoubleArray>(java_data.l), 0, 1, static_cast<jdouble *>(uno_data) );
359 jni.ensure_no_exception();
361 else if (special_wrapped_integral_types)
363 *static_cast<jdouble *>(uno_data) = jni->CallDoubleMethodA(
364 java_data.l, getJniInfo()->m_method_Double_doubleValue, nullptr );
365 jni.ensure_no_exception();
367 else
369 *static_cast<jdouble *>(uno_data) = java_data.d;
371 break;
372 case typelib_TypeClass_STRING:
374 JLocalAutoRef jo_out_holder( jni );
375 if (out_param)
377 jo_out_holder.reset(
378 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
379 jni.ensure_no_exception();
380 java_data.l = jo_out_holder.get();
382 if (java_data.l == nullptr)
384 throw BridgeRuntimeError(
385 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
386 + "] null-ref given!" + jni.get_stack_trace() );
388 if (! assign)
389 *static_cast<rtl_uString **>(uno_data) = nullptr;
390 jstring_to_ustring(
391 jni, static_cast<rtl_uString **>(uno_data), static_cast<jstring>(java_data.l) );
392 break;
394 case typelib_TypeClass_TYPE:
396 JLocalAutoRef jo_out_holder( jni );
397 if (out_param)
399 jo_out_holder.reset(
400 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
401 jni.ensure_no_exception();
402 java_data.l = jo_out_holder.get();
404 if (java_data.l == nullptr)
406 throw BridgeRuntimeError(
407 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
408 + "] null-ref given!" + jni.get_stack_trace() );
411 // type name
412 JLocalAutoRef jo_type_name(
413 jni, jni->GetObjectField(
414 java_data.l, getJniInfo()->m_field_Type_typeName ) );
415 if (! jo_type_name.is())
417 throw BridgeRuntimeError(
418 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
419 + "] incomplete type object: no type name!"
420 + jni.get_stack_trace() );
422 OUString type_name(
423 jstring_to_oustring( jni, static_cast<jstring>(jo_type_name.get()) ) );
424 ::com::sun::star::uno::TypeDescription td( type_name );
425 if (! td.is())
427 throw BridgeRuntimeError(
428 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
429 + "] UNO type not found: " + type_name
430 + jni.get_stack_trace() );
432 typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
433 if (assign)
435 typelib_typedescriptionreference_release(
436 *static_cast<typelib_TypeDescriptionReference **>(uno_data) );
438 *static_cast<typelib_TypeDescriptionReference **>(uno_data) = td.get()->pWeakRef;
439 break;
441 case typelib_TypeClass_ANY:
443 JLocalAutoRef jo_out_holder( jni );
444 if (out_param)
446 jo_out_holder.reset(
447 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
448 jni.ensure_no_exception();
449 java_data.l = jo_out_holder.get();
452 uno_Any * pAny = static_cast<uno_Any *>(uno_data);
453 if (java_data.l == nullptr) // null-ref maps to XInterface null-ref
455 if (assign)
456 uno_any_destruct( pAny, nullptr );
457 uno_any_construct(
458 pAny, nullptr, getJniInfo()->m_XInterface_type_info->m_td.get(), nullptr );
459 break;
462 JLocalAutoRef jo_type( jni );
463 JLocalAutoRef jo_wrapped_holder( jni );
465 if (jni->IsInstanceOf( java_data.l, getJniInfo()->m_class_Any ))
467 // boxed any
468 jo_type.reset( jni->GetObjectField(
469 java_data.l, getJniInfo()->m_field_Any_type ) );
470 if (! jo_type.is())
472 throw BridgeRuntimeError(
473 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
474 + "] no type set at com.sun.star.uno.Any!"
475 + jni.get_stack_trace() );
477 // wrapped value
478 jo_wrapped_holder.reset(
479 jni->GetObjectField(
480 java_data.l, getJniInfo()->m_field_Any_object ) );
481 java_data.l = jo_wrapped_holder.get();
483 else
485 // create type out of class
486 JLocalAutoRef jo_class( jni, jni->GetObjectClass( java_data.l ) );
487 jo_type.reset( create_type( jni, static_cast<jclass>(jo_class.get()) ) );
490 // get type name
491 JLocalAutoRef jo_type_name(
492 jni, jni->GetObjectField(
493 jo_type.get(), getJniInfo()->m_field_Type_typeName ) );
494 jni.ensure_no_exception();
495 OUString type_name(
496 jstring_to_oustring( jni, static_cast<jstring>(jo_type_name.get()) ) );
498 ::com::sun::star::uno::TypeDescription value_td( type_name );
499 if (! value_td.is())
501 throw BridgeRuntimeError(
502 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
503 + "] UNO type not found: " + type_name
504 + jni.get_stack_trace() );
506 typelib_TypeClass type_class = value_td.get()->eTypeClass;
508 if (assign)
510 uno_any_destruct( pAny, nullptr );
514 switch (type_class)
516 case typelib_TypeClass_VOID:
517 pAny->pData = &pAny->pReserved;
518 break;
519 case typelib_TypeClass_CHAR:
520 pAny->pData = &pAny->pReserved;
521 *static_cast<jchar *>(pAny->pData) = jni->CallCharMethodA(
522 java_data.l, getJniInfo()->m_method_Character_charValue, nullptr );
523 jni.ensure_no_exception();
524 break;
525 case typelib_TypeClass_BOOLEAN:
526 pAny->pData = &pAny->pReserved;
527 *static_cast<jboolean *>(pAny->pData) = jni->CallBooleanMethodA(
528 java_data.l, getJniInfo()->m_method_Boolean_booleanValue, nullptr );
529 jni.ensure_no_exception();
530 break;
531 case typelib_TypeClass_BYTE:
532 pAny->pData = &pAny->pReserved;
533 *static_cast<jbyte *>(pAny->pData) = jni->CallByteMethodA(
534 java_data.l, getJniInfo()->m_method_Byte_byteValue, nullptr );
535 jni.ensure_no_exception();
536 break;
537 case typelib_TypeClass_SHORT:
538 case typelib_TypeClass_UNSIGNED_SHORT:
539 pAny->pData = &pAny->pReserved;
540 *static_cast<jshort *>(pAny->pData) = jni->CallShortMethodA(
541 java_data.l, getJniInfo()->m_method_Short_shortValue, nullptr );
542 jni.ensure_no_exception();
543 break;
544 case typelib_TypeClass_LONG:
545 case typelib_TypeClass_UNSIGNED_LONG:
546 pAny->pData = &pAny->pReserved;
547 *static_cast<jint *>(pAny->pData) = jni->CallIntMethodA(
548 java_data.l, getJniInfo()->m_method_Integer_intValue, nullptr );
549 jni.ensure_no_exception();
550 break;
551 case typelib_TypeClass_HYPER:
552 case typelib_TypeClass_UNSIGNED_HYPER:
553 if (sizeof (sal_Int64) <= sizeof (void *))
555 pAny->pData = &pAny->pReserved;
556 *static_cast<jlong *>(pAny->pData) = jni->CallLongMethodA(
557 java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
558 jni.ensure_no_exception();
560 else
562 std::unique_ptr< rtl_mem > mem(
563 rtl_mem::allocate( sizeof (sal_Int64) ) );
564 *reinterpret_cast<jlong *>(mem.get()) = jni->CallLongMethodA(
565 java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
566 jni.ensure_no_exception();
567 pAny->pData = mem.release();
569 break;
570 case typelib_TypeClass_FLOAT:
571 if (sizeof (float) <= sizeof (void *))
573 pAny->pData = &pAny->pReserved;
574 *static_cast<jfloat *>(pAny->pData) = jni->CallFloatMethodA(
575 java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
576 jni.ensure_no_exception();
578 else
580 std::unique_ptr< rtl_mem > mem(
581 rtl_mem::allocate( sizeof (float) ) );
582 *reinterpret_cast<jfloat *>(mem.get()) = jni->CallFloatMethodA(
583 java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
584 jni.ensure_no_exception();
585 pAny->pData = mem.release();
587 break;
588 case typelib_TypeClass_DOUBLE:
589 if (sizeof (double) <= sizeof (void *))
591 pAny->pData = &pAny->pReserved;
592 *static_cast<jdouble *>(pAny->pData) =
593 jni->CallDoubleMethodA(
594 java_data.l,
595 getJniInfo()->m_method_Double_doubleValue, nullptr );
596 jni.ensure_no_exception();
598 else
600 std::unique_ptr< rtl_mem > mem(
601 rtl_mem::allocate( sizeof (double) ) );
602 *reinterpret_cast<jdouble *>(mem.get()) =
603 jni->CallDoubleMethodA(
604 java_data.l,
605 getJniInfo()->m_method_Double_doubleValue, nullptr );
606 jni.ensure_no_exception();
607 pAny->pData = mem.release();
609 break;
610 case typelib_TypeClass_STRING:
611 // opt: anies often contain strings; copy string directly
612 pAny->pReserved = nullptr;
613 pAny->pData = &pAny->pReserved;
614 jstring_to_ustring(
615 jni, static_cast<rtl_uString **>(pAny->pData),
616 static_cast<jstring>(java_data.l) );
617 break;
618 case typelib_TypeClass_TYPE:
619 case typelib_TypeClass_ENUM:
620 case typelib_TypeClass_SEQUENCE:
621 case typelib_TypeClass_INTERFACE:
622 pAny->pData = &pAny->pReserved;
623 map_to_uno(
624 jni, pAny->pData, java_data,
625 value_td.get()->pWeakRef, nullptr,
626 false /* no assign */, false /* no out param */ );
627 break;
628 case typelib_TypeClass_STRUCT:
629 case typelib_TypeClass_EXCEPTION:
631 std::unique_ptr< rtl_mem > mem(
632 rtl_mem::allocate( value_td.get()->nSize ) );
633 map_to_uno(
634 jni, mem.get(), java_data, value_td.get()->pWeakRef, nullptr,
635 false /* no assign */, false /* no out param */ );
636 pAny->pData = mem.release();
637 break;
639 default:
641 throw BridgeRuntimeError(
642 "[map_to_uno():" + type_name
643 + "] unsupported value type of any!"
644 + jni.get_stack_trace() );
648 catch (...)
650 if (assign)
652 // restore to valid any
653 uno_any_construct( pAny, nullptr, nullptr, nullptr );
655 throw;
657 typelib_typedescriptionreference_acquire( value_td.get()->pWeakRef );
658 pAny->pType = value_td.get()->pWeakRef;
659 break;
661 case typelib_TypeClass_ENUM:
663 JLocalAutoRef jo_out_holder( jni );
664 if (out_param)
666 jo_out_holder.reset(
667 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
668 jni.ensure_no_exception();
669 java_data.l = jo_out_holder.get();
671 if (java_data.l == nullptr)
673 throw BridgeRuntimeError(
674 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
675 + "] null-ref given!" + jni.get_stack_trace() );
678 *static_cast<jint *>(uno_data) = jni->GetIntField(
679 java_data.l, getJniInfo()->m_field_Enum_m_value );
680 break;
682 case typelib_TypeClass_STRUCT:
683 case typelib_TypeClass_EXCEPTION:
685 JLocalAutoRef jo_out_holder( jni );
686 if (out_param)
688 jo_out_holder.reset(
689 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
690 jni.ensure_no_exception();
691 java_data.l = jo_out_holder.get();
693 if (java_data.l == nullptr)
695 throw BridgeRuntimeError(
696 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
697 + "] null-ref given!" + jni.get_stack_trace() );
700 if (info == nullptr)
701 info = getJniInfo()->get_type_info( jni, type );
702 JNI_compound_type_info const * comp_info =
703 static_cast< JNI_compound_type_info const * >( info );
705 typelib_CompoundTypeDescription * comp_td =
706 reinterpret_cast<typelib_CompoundTypeDescription *>(comp_info->m_td.get());
707 bool polymorphic
708 = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
709 && reinterpret_cast< typelib_StructTypeDescription * >(
710 comp_td)->pParameterizedTypes != nullptr;
712 sal_Int32 nPos = 0;
713 sal_Int32 nMembers = comp_td->nMembers;
716 if (comp_td->pBaseTypeDescription != nullptr)
718 map_to_uno(
719 jni, uno_data, java_data,
720 comp_td->pBaseTypeDescription->aBase.pWeakRef,
721 comp_info->m_base,
722 assign, false /* no out param */ );
725 for ( ; nPos < nMembers; ++nPos )
727 void * p = static_cast<char *>(uno_data) + comp_td->pMemberOffsets[ nPos ];
728 typelib_TypeDescriptionReference * member_type =
729 comp_td->ppTypeRefs[ nPos ];
730 jfieldID field_id = comp_info->m_fields[ nPos ];
731 bool parameterizedType = polymorphic
732 && reinterpret_cast< typelib_StructTypeDescription * >(
733 comp_td)->pParameterizedTypes[nPos];
734 switch (member_type->eTypeClass)
736 case typelib_TypeClass_CHAR:
737 if (parameterizedType) {
738 JLocalAutoRef jo(
739 jni, jni->GetObjectField( java_data.l, field_id ) );
740 if ( jo.get() == nullptr ) {
741 *static_cast<jchar *>(p) = 0;
742 } else {
743 jvalue val;
744 val.l = jo.get();
745 map_to_uno(
746 jni, p, val, member_type, nullptr, assign, false,
747 true );
749 } else {
750 *static_cast<jchar *>(p) = jni->GetCharField(
751 java_data.l, field_id );
753 break;
754 case typelib_TypeClass_BOOLEAN:
755 if (parameterizedType) {
756 JLocalAutoRef jo(
757 jni, jni->GetObjectField( java_data.l, field_id ) );
758 if ( jo.get() == nullptr ) {
759 *static_cast<jboolean *>(p) = false;
760 } else {
761 jvalue val;
762 val.l = jo.get();
763 map_to_uno(
764 jni, p, val, member_type, nullptr, assign, false,
765 true );
767 } else {
768 *static_cast<jboolean *>(p) = jni->GetBooleanField(
769 java_data.l, field_id );
771 break;
772 case typelib_TypeClass_BYTE:
773 if (parameterizedType) {
774 JLocalAutoRef jo(
775 jni, jni->GetObjectField( java_data.l, field_id ) );
776 if ( jo.get() == nullptr ) {
777 *static_cast<jbyte *>(p) = 0;
778 } else {
779 jvalue val;
780 val.l = jo.get();
781 map_to_uno(
782 jni, p, val, member_type, nullptr, assign, false,
783 true );
785 } else {
786 *static_cast<jbyte *>(p) = jni->GetByteField(
787 java_data.l, field_id );
789 break;
790 case typelib_TypeClass_SHORT:
791 case typelib_TypeClass_UNSIGNED_SHORT:
792 if (parameterizedType) {
793 JLocalAutoRef jo(
794 jni, jni->GetObjectField( java_data.l, field_id ) );
795 if ( jo.get() == nullptr ) {
796 *static_cast<jshort *>(p) = 0;
797 } else {
798 jvalue val;
799 val.l = jo.get();
800 map_to_uno(
801 jni, p, val, member_type, nullptr, assign, false,
802 true );
804 } else {
805 *static_cast<jshort *>(p) = jni->GetShortField(
806 java_data.l, field_id );
808 break;
809 case typelib_TypeClass_LONG:
810 case typelib_TypeClass_UNSIGNED_LONG:
811 if (parameterizedType) {
812 JLocalAutoRef jo(
813 jni, jni->GetObjectField( java_data.l, field_id ) );
814 if ( jo.get() == nullptr ) {
815 *static_cast<jint *>(p) = 0;
816 } else {
817 jvalue val;
818 val.l = jo.get();
819 map_to_uno(
820 jni, p, val, member_type, nullptr, assign, false,
821 true );
823 } else {
824 *static_cast<jint *>(p) = jni->GetIntField( java_data.l, field_id );
826 break;
827 case typelib_TypeClass_HYPER:
828 case typelib_TypeClass_UNSIGNED_HYPER:
829 if (parameterizedType) {
830 JLocalAutoRef jo(
831 jni, jni->GetObjectField( java_data.l, field_id ) );
832 if ( jo.get() == nullptr ) {
833 *static_cast<jlong *>(p) = 0;
834 } else {
835 jvalue val;
836 val.l = jo.get();
837 map_to_uno(
838 jni, p, val, member_type, nullptr, assign, false,
839 true );
841 } else {
842 *static_cast<jlong *>(p) = jni->GetLongField(
843 java_data.l, field_id );
845 break;
846 case typelib_TypeClass_FLOAT:
847 if (parameterizedType) {
848 JLocalAutoRef jo(
849 jni, jni->GetObjectField( java_data.l, field_id ) );
850 if ( jo.get() == nullptr ) {
851 *static_cast<jfloat *>(p) = 0;
852 } else {
853 jvalue val;
854 val.l = jo.get();
855 map_to_uno(
856 jni, p, val, member_type, nullptr, assign, false,
857 true );
859 } else {
860 *static_cast<jfloat *>(p) = jni->GetFloatField(
861 java_data.l, field_id );
863 break;
864 case typelib_TypeClass_DOUBLE:
865 if (parameterizedType) {
866 JLocalAutoRef jo(
867 jni, jni->GetObjectField( java_data.l, field_id ) );
868 if ( jo.get() == nullptr ) {
869 *static_cast<jdouble *>(p) = 0;
870 } else {
871 jvalue val;
872 val.l = jo.get();
873 map_to_uno(
874 jni, p, val, member_type, nullptr, assign, false,
875 true );
877 } else {
878 *static_cast<jdouble *>(p) = jni->GetDoubleField(
879 java_data.l, field_id );
881 break;
882 default:
884 JLocalAutoRef jo_field( jni );
885 bool checkNull;
886 if (field_id == nullptr)
888 // special for Message: call Throwable.getMessage()
889 assert(
890 type_equals(
891 type,
892 getJniInfo()->m_Exception_type.getTypeLibType() )
893 || type_equals(
894 type,
895 getJniInfo()->m_RuntimeException_type.
896 getTypeLibType() ) );
897 assert( nPos == 0 ); // first member
898 // call getMessage()
899 jo_field.reset(
900 jni->CallObjectMethodA(
901 java_data.l,
902 getJniInfo()->m_method_Throwable_getMessage, nullptr )
904 jni.ensure_no_exception();
905 checkNull = true;
907 else
909 jo_field.reset(
910 jni->GetObjectField( java_data.l, field_id ) );
911 checkNull = parameterizedType;
913 if (checkNull && !jo_field.is()) {
914 createDefaultUnoValue(jni, p, member_type, nullptr, assign);
915 } else {
916 jvalue val;
917 val.l = jo_field.get();
918 map_to_uno(
919 jni, p, val, member_type, nullptr,
920 assign, false /* no out param */ );
922 break;
927 catch (...)
929 if (! assign)
931 // cleanup
932 for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
934 void * p =
935 static_cast<char *>(uno_data) + comp_td->pMemberOffsets[ nCleanup ];
936 uno_type_destructData(
937 p, comp_td->ppTypeRefs[ nCleanup ], nullptr );
939 if (comp_td->pBaseTypeDescription != nullptr)
941 uno_destructData(
942 uno_data, &comp_td->pBaseTypeDescription->aBase, nullptr );
945 throw;
947 break;
949 case typelib_TypeClass_SEQUENCE:
951 JLocalAutoRef jo_out_holder( jni );
952 if (out_param)
954 jo_out_holder.reset(
955 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
956 jni.ensure_no_exception();
957 java_data.l = jo_out_holder.get();
959 if (java_data.l == nullptr)
961 throw BridgeRuntimeError(
962 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
963 + "] null-ref given!" + jni.get_stack_trace() );
966 TypeDescr td( type );
967 typelib_TypeDescriptionReference * element_type =
968 reinterpret_cast<typelib_IndirectTypeDescription *>(td.get())->pType;
970 std::unique_ptr< rtl_mem > seq;
971 sal_Int32 nElements = jni->GetArrayLength( static_cast<jarray>(java_data.l) );
973 switch (element_type->eTypeClass)
975 case typelib_TypeClass_CHAR:
976 seq = seq_allocate( nElements, sizeof (sal_Unicode) );
977 jni->GetCharArrayRegion(
978 static_cast<jcharArray>(java_data.l), 0, nElements,
979 reinterpret_cast<jchar *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
980 jni.ensure_no_exception();
981 break;
982 case typelib_TypeClass_BOOLEAN:
983 seq = seq_allocate( nElements, sizeof (sal_Bool) );
984 jni->GetBooleanArrayRegion(
985 static_cast<jbooleanArray>(java_data.l), 0, nElements,
986 reinterpret_cast<jboolean *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
987 jni.ensure_no_exception();
988 break;
989 case typelib_TypeClass_BYTE:
990 seq = seq_allocate( nElements, sizeof (sal_Int8) );
991 jni->GetByteArrayRegion(
992 static_cast<jbyteArray>(java_data.l), 0, nElements,
993 reinterpret_cast<jbyte *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
994 jni.ensure_no_exception();
995 break;
996 case typelib_TypeClass_SHORT:
997 case typelib_TypeClass_UNSIGNED_SHORT:
998 seq = seq_allocate( nElements, sizeof (sal_Int16) );
999 jni->GetShortArrayRegion(
1000 static_cast<jshortArray>(java_data.l), 0, nElements,
1001 reinterpret_cast<jshort *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1002 jni.ensure_no_exception();
1003 break;
1004 case typelib_TypeClass_LONG:
1005 case typelib_TypeClass_UNSIGNED_LONG:
1006 seq = seq_allocate( nElements, sizeof (sal_Int32) );
1007 jni->GetIntArrayRegion(
1008 static_cast<jintArray>(java_data.l), 0, nElements,
1009 reinterpret_cast<jint *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1010 jni.ensure_no_exception();
1011 break;
1012 case typelib_TypeClass_HYPER:
1013 case typelib_TypeClass_UNSIGNED_HYPER:
1014 seq = seq_allocate( nElements, sizeof (sal_Int64) );
1015 jni->GetLongArrayRegion(
1016 static_cast<jlongArray>(java_data.l), 0, nElements,
1017 reinterpret_cast<jlong *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1018 jni.ensure_no_exception();
1019 break;
1020 case typelib_TypeClass_FLOAT:
1021 seq = seq_allocate( nElements, sizeof (float) );
1022 jni->GetFloatArrayRegion(
1023 static_cast<jfloatArray>(java_data.l), 0, nElements,
1024 reinterpret_cast<jfloat *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1025 jni.ensure_no_exception();
1026 break;
1027 case typelib_TypeClass_DOUBLE:
1028 seq = seq_allocate( nElements, sizeof (double) );
1029 jni->GetDoubleArrayRegion(
1030 static_cast<jdoubleArray>(java_data.l), 0, nElements,
1031 reinterpret_cast<jdouble *>(reinterpret_cast<uno_Sequence *>(seq.get())->elements) );
1032 jni.ensure_no_exception();
1033 break;
1034 case typelib_TypeClass_STRING:
1035 case typelib_TypeClass_TYPE:
1036 case typelib_TypeClass_ANY:
1037 case typelib_TypeClass_ENUM:
1038 case typelib_TypeClass_STRUCT:
1039 case typelib_TypeClass_EXCEPTION:
1040 case typelib_TypeClass_SEQUENCE:
1041 case typelib_TypeClass_INTERFACE:
1043 TypeDescr element_td( element_type );
1044 seq = seq_allocate( nElements, element_td.get()->nSize );
1046 JNI_type_info const * element_info;
1047 if (element_type->eTypeClass == typelib_TypeClass_STRUCT ||
1048 element_type->eTypeClass == typelib_TypeClass_EXCEPTION ||
1049 element_type->eTypeClass == typelib_TypeClass_INTERFACE)
1051 element_info =
1052 getJniInfo()->get_type_info( jni, element_td.get() );
1054 else
1056 element_info = nullptr;
1059 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1063 JLocalAutoRef jo(
1064 jni, jni->GetObjectArrayElement(
1065 static_cast<jobjectArray>(java_data.l), nPos ) );
1066 jni.ensure_no_exception();
1067 jvalue val;
1068 val.l = jo.get();
1069 void * p =
1070 reinterpret_cast<uno_Sequence *>(seq.get())->elements +
1071 (nPos * element_td.get()->nSize);
1072 map_to_uno(
1073 jni, p, val, element_td.get()->pWeakRef, element_info,
1074 false /* no assign */, false /* no out param */ );
1076 catch (...)
1078 // cleanup
1079 for ( sal_Int32 nCleanPos = 0;
1080 nCleanPos < nPos; ++nCleanPos )
1082 void * p =
1083 reinterpret_cast<uno_Sequence *>(seq.get())->elements +
1084 (nCleanPos * element_td.get()->nSize);
1085 uno_destructData( p, element_td.get(), nullptr );
1087 throw;
1090 break;
1092 default:
1094 throw BridgeRuntimeError(
1095 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
1096 + "] unsupported sequence element type: "
1097 + OUString::unacquired( &element_type->pTypeName )
1098 + jni.get_stack_trace() );
1102 if (assign)
1103 uno_destructData( uno_data, td.get(), nullptr );
1104 *static_cast<uno_Sequence **>(uno_data) = reinterpret_cast<uno_Sequence *>(seq.release());
1105 break;
1107 case typelib_TypeClass_INTERFACE:
1109 JLocalAutoRef jo_out_holder( jni );
1110 if (out_param)
1112 jo_out_holder.reset(
1113 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
1114 jni.ensure_no_exception();
1115 java_data.l = jo_out_holder.get();
1118 if (java_data.l == nullptr) // null-ref
1120 if (assign)
1122 uno_Interface * p = *static_cast<uno_Interface **>(uno_data);
1123 if (p != nullptr)
1124 (*p->release)( p );
1126 *static_cast<uno_Interface **>(uno_data) = nullptr;
1128 else
1130 if (info == nullptr)
1131 info = getJniInfo()->get_type_info( jni, type );
1132 JNI_interface_type_info const * iface_info =
1133 static_cast< JNI_interface_type_info const * >( info );
1134 uno_Interface * pUnoI = map_to_uno( jni, java_data.l, iface_info );
1135 if (assign)
1137 uno_Interface * p = *static_cast<uno_Interface **>(uno_data);
1138 if (p != nullptr)
1139 (*p->release)( p );
1141 *static_cast<uno_Interface **>(uno_data) = pUnoI;
1143 break;
1145 default:
1147 throw BridgeRuntimeError(
1148 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
1149 + "] 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 (java_data->l == nullptr)
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 (java_data->l == nullptr)
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 (java_data->l == nullptr)
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 (java_data->l == nullptr)
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 (java_data->l == nullptr)
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 (java_data->l == nullptr)
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 (java_data->l == nullptr)
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 (java_data->l == nullptr)
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 (java_data->l == nullptr)
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 (java_data->l == nullptr)
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, nullptr,
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 (element_type.getTypeLibType()->eTypeClass ==
1647 typelib_TypeClass_SEQUENCE)
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 (pUnoI != nullptr)
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 (pUnoI != nullptr)
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, nullptr, 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 [[fallthrough]];
1743 default:
1745 jvalue java_data2;
1746 map_to_java(
1747 jni, &java_data2, pAny->pData, pAny->pType, nullptr,
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 (java_data->l == nullptr)
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 OString sig = "(I)L" + class_name.replace( '.', '/' ) + ";";
1790 jmethodID method_id = jni->GetStaticMethodID(
1791 static_cast<jclass>(jo_enum_class.get()), "fromInt", sig.getStr() );
1792 jni.ensure_no_exception();
1793 assert( method_id != nullptr );
1795 jvalue arg;
1796 arg.i = *static_cast<jint const *>(uno_data);
1797 jo_enum.reset(
1798 jni->CallStaticObjectMethodA(
1799 static_cast<jclass>(jo_enum_class.get()), method_id, &arg ) );
1800 jni.ensure_no_exception();
1802 if (out_param)
1804 if (java_data->l == nullptr)
1806 java_data->l = jni->NewObjectArray(
1807 1, static_cast<jclass>(jo_enum_class.get()), jo_enum.get() );
1808 jni.ensure_no_exception();
1810 else
1812 jni->SetObjectArrayElement(
1813 static_cast<jobjectArray>(java_data->l), 0, jo_enum.get() );
1814 jni.ensure_no_exception();
1817 else
1819 java_data->l = jo_enum.release();
1821 break;
1823 case typelib_TypeClass_STRUCT:
1824 case typelib_TypeClass_EXCEPTION:
1826 if (info == nullptr)
1827 info = getJniInfo()->get_type_info( jni, type );
1828 JNI_compound_type_info const * comp_info =
1829 static_cast< JNI_compound_type_info const * >( info );
1831 JLocalAutoRef jo_comp( jni );
1832 if (in_param)
1834 if (type->eTypeClass == typelib_TypeClass_EXCEPTION)
1836 JLocalAutoRef jo_message(
1837 jni, ustring_to_jstring( jni, *static_cast<rtl_uString * const *>(uno_data) ) );
1838 jvalue arg;
1839 arg.l = jo_message.get();
1840 jo_comp.reset(
1841 jni->NewObjectA(
1842 comp_info->m_class, comp_info->m_exc_ctor, &arg ) );
1843 jni.ensure_no_exception();
1845 else
1847 jo_comp.reset( jni->AllocObject( comp_info->m_class ) );
1848 jni.ensure_no_exception();
1851 for ( JNI_compound_type_info const * linfo = comp_info;
1852 linfo != nullptr;
1853 linfo = static_cast< JNI_compound_type_info const * >(
1854 linfo->m_base ) )
1856 typelib_CompoundTypeDescription * comp_td =
1857 reinterpret_cast<typelib_CompoundTypeDescription *>(linfo->m_td.get());
1858 typelib_TypeDescriptionReference ** ppMemberTypeRefs =
1859 comp_td->ppTypeRefs;
1860 sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
1861 bool polymorphic
1862 = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
1863 && reinterpret_cast< typelib_StructTypeDescription * >(
1864 comp_td)->pParameterizedTypes != nullptr;
1865 for ( sal_Int32 nPos = comp_td->nMembers; nPos--; )
1867 jfieldID field_id = linfo->m_fields[ nPos ];
1868 if (field_id != nullptr)
1870 void const * p =
1871 static_cast<char const *>(uno_data) + pMemberOffsets[ nPos ];
1872 typelib_TypeDescriptionReference * member_type =
1873 ppMemberTypeRefs[ nPos ];
1874 bool parameterizedType = polymorphic
1875 && (reinterpret_cast<
1876 typelib_StructTypeDescription * >(comp_td)->
1877 pParameterizedTypes[nPos]);
1878 switch (member_type->eTypeClass)
1880 case typelib_TypeClass_CHAR:
1881 if (parameterizedType) {
1882 jvalue arg;
1883 arg.c = *static_cast<jchar const *>(p);
1884 JLocalAutoRef jo(
1885 jni,
1886 jni->NewObjectA(
1887 getJniInfo()->m_class_Character,
1888 getJniInfo()->m_ctor_Character_with_char,
1889 &arg ) );
1890 jni.ensure_no_exception();
1891 jni->SetObjectField(
1892 jo_comp.get(), field_id, jo.get() );
1893 } else {
1894 jni->SetCharField(
1895 jo_comp.get(),
1896 field_id, *static_cast<jchar const *>(p) );
1898 break;
1899 case typelib_TypeClass_BOOLEAN:
1900 if (parameterizedType) {
1901 jvalue arg;
1902 arg.z = *static_cast<jboolean const *>(p);
1903 JLocalAutoRef jo(
1904 jni,
1905 jni->NewObjectA(
1906 getJniInfo()->m_class_Boolean,
1907 getJniInfo()->m_ctor_Boolean_with_boolean,
1908 &arg ) );
1909 jni.ensure_no_exception();
1910 jni->SetObjectField(
1911 jo_comp.get(), field_id, jo.get() );
1912 } else {
1913 jni->SetBooleanField(
1914 jo_comp.get(),
1915 field_id, *static_cast<jboolean const *>(p) );
1917 break;
1918 case typelib_TypeClass_BYTE:
1919 if (parameterizedType) {
1920 jvalue arg;
1921 arg.b = *static_cast<jbyte const *>(p);
1922 JLocalAutoRef jo(
1923 jni,
1924 jni->NewObjectA(
1925 getJniInfo()->m_class_Byte,
1926 getJniInfo()->m_ctor_Byte_with_byte,
1927 &arg ) );
1928 jni.ensure_no_exception();
1929 jni->SetObjectField(
1930 jo_comp.get(), field_id, jo.get() );
1931 } else {
1932 jni->SetByteField(
1933 jo_comp.get(),
1934 field_id, *static_cast<jbyte const *>(p) );
1936 break;
1937 case typelib_TypeClass_SHORT:
1938 case typelib_TypeClass_UNSIGNED_SHORT:
1939 if (parameterizedType) {
1940 jvalue arg;
1941 arg.s = *static_cast<jshort const *>(p);
1942 JLocalAutoRef jo(
1943 jni,
1944 jni->NewObjectA(
1945 getJniInfo()->m_class_Short,
1946 getJniInfo()->m_ctor_Short_with_short,
1947 &arg ) );
1948 jni.ensure_no_exception();
1949 jni->SetObjectField(
1950 jo_comp.get(), field_id, jo.get() );
1951 } else {
1952 jni->SetShortField(
1953 jo_comp.get(),
1954 field_id, *static_cast<jshort const *>(p) );
1956 break;
1957 case typelib_TypeClass_LONG:
1958 case typelib_TypeClass_UNSIGNED_LONG:
1959 if (parameterizedType) {
1960 jvalue arg;
1961 arg.i = *static_cast<jint const *>(p);
1962 JLocalAutoRef jo(
1963 jni,
1964 jni->NewObjectA(
1965 getJniInfo()->m_class_Integer,
1966 getJniInfo()->m_ctor_Integer_with_int,
1967 &arg ) );
1968 jni.ensure_no_exception();
1969 jni->SetObjectField(
1970 jo_comp.get(), field_id, jo.get() );
1971 } else {
1972 jni->SetIntField(
1973 jo_comp.get(),
1974 field_id, *static_cast<jint const *>(p) );
1976 break;
1977 case typelib_TypeClass_HYPER:
1978 case typelib_TypeClass_UNSIGNED_HYPER:
1979 if (parameterizedType) {
1980 jvalue arg;
1981 arg.j = *static_cast<jlong const *>(p);
1982 JLocalAutoRef jo(
1983 jni,
1984 jni->NewObjectA(
1985 getJniInfo()->m_class_Long,
1986 getJniInfo()->m_ctor_Long_with_long,
1987 &arg ) );
1988 jni.ensure_no_exception();
1989 jni->SetObjectField(
1990 jo_comp.get(), field_id, jo.get() );
1991 } else {
1992 jni->SetLongField(
1993 jo_comp.get(),
1994 field_id, *static_cast<jlong const *>(p) );
1996 break;
1997 case typelib_TypeClass_FLOAT:
1998 if (parameterizedType) {
1999 jvalue arg;
2000 arg.f = *static_cast<jfloat const *>(p);
2001 JLocalAutoRef jo(
2002 jni,
2003 jni->NewObjectA(
2004 getJniInfo()->m_class_Float,
2005 getJniInfo()->m_ctor_Float_with_float,
2006 &arg ) );
2007 jni.ensure_no_exception();
2008 jni->SetObjectField(
2009 jo_comp.get(), field_id, jo.get() );
2010 } else {
2011 jni->SetFloatField(
2012 jo_comp.get(),
2013 field_id, *static_cast<jfloat const *>(p) );
2015 break;
2016 case typelib_TypeClass_DOUBLE:
2017 if (parameterizedType) {
2018 jvalue arg;
2019 arg.d = *static_cast<jdouble const *>(p);
2020 JLocalAutoRef jo(
2021 jni,
2022 jni->NewObjectA(
2023 getJniInfo()->m_class_Double,
2024 getJniInfo()->m_ctor_Double_with_double,
2025 &arg ) );
2026 jni.ensure_no_exception();
2027 jni->SetObjectField(
2028 jo_comp.get(), field_id, jo.get() );
2029 } else {
2030 jni->SetDoubleField(
2031 jo_comp.get(),
2032 field_id, *static_cast<jdouble const *>(p) );
2034 break;
2035 case typelib_TypeClass_STRING: // string opt here
2037 JLocalAutoRef jo_string(
2038 jni, ustring_to_jstring(
2039 jni, *static_cast<rtl_uString * const *>(p) ) );
2040 jni->SetObjectField(
2041 jo_comp.get(), field_id, jo_string.get() );
2042 break;
2044 default:
2046 jvalue java_data2;
2047 map_to_java(
2048 jni, &java_data2, p, member_type, nullptr,
2049 true /* in */, false /* no out */ );
2050 JLocalAutoRef jo_obj( jni, java_data2.l );
2051 jni->SetObjectField(
2052 jo_comp.get(), field_id, jo_obj.get() );
2053 break;
2060 if (out_param)
2062 if (java_data->l == nullptr)
2064 java_data->l =
2065 jni->NewObjectArray( 1, comp_info->m_class, jo_comp.get() );
2066 jni.ensure_no_exception();
2068 else
2070 jni->SetObjectArrayElement(
2071 static_cast<jobjectArray>(java_data->l), 0, jo_comp.get() );
2072 jni.ensure_no_exception();
2075 else
2077 java_data->l = jo_comp.release();
2079 break;
2081 case typelib_TypeClass_SEQUENCE:
2083 // xxx todo: possible opt for pure out sequences
2084 JLocalAutoRef jo_ar( jni );
2086 sal_Int32 nElements;
2087 uno_Sequence * seq = nullptr;
2088 if (in_param)
2090 seq = *static_cast<uno_Sequence * const *>(uno_data);
2091 nElements = seq->nElements;
2093 else
2095 nElements = 0;
2098 TypeDescr td( type );
2099 typelib_TypeDescriptionReference * element_type =
2100 reinterpret_cast<typelib_IndirectTypeDescription *>(td.get())->pType;
2102 switch (element_type->eTypeClass)
2104 case typelib_TypeClass_CHAR:
2105 jo_ar.reset( jni->NewCharArray( nElements ) );
2106 jni.ensure_no_exception();
2107 if (0 < nElements)
2109 jni->SetCharArrayRegion(
2110 static_cast<jcharArray>(jo_ar.get()),
2111 0, nElements, reinterpret_cast<jchar *>(seq->elements) );
2112 jni.ensure_no_exception();
2114 break;
2115 case typelib_TypeClass_BOOLEAN:
2116 jo_ar.reset( jni->NewBooleanArray( nElements ) );
2117 jni.ensure_no_exception();
2118 if (0 < nElements)
2120 jni->SetBooleanArrayRegion(
2121 static_cast<jbooleanArray>(jo_ar.get()),
2122 0, nElements, reinterpret_cast<jboolean *>(seq->elements) );
2123 jni.ensure_no_exception();
2125 break;
2126 case typelib_TypeClass_BYTE:
2127 jo_ar.reset( jni->NewByteArray( nElements ) );
2128 jni.ensure_no_exception();
2129 if (0 < nElements)
2131 jni->SetByteArrayRegion(
2132 static_cast<jbyteArray>(jo_ar.get()),
2133 0, nElements, reinterpret_cast<jbyte *>(seq->elements) );
2134 jni.ensure_no_exception();
2136 break;
2137 case typelib_TypeClass_SHORT:
2138 case typelib_TypeClass_UNSIGNED_SHORT:
2139 jo_ar.reset( jni->NewShortArray( nElements ) );
2140 jni.ensure_no_exception();
2141 if (0 < nElements)
2143 jni->SetShortArrayRegion(
2144 static_cast<jshortArray>(jo_ar.get()),
2145 0, nElements, reinterpret_cast<jshort *>(seq->elements) );
2146 jni.ensure_no_exception();
2148 break;
2149 case typelib_TypeClass_LONG:
2150 case typelib_TypeClass_UNSIGNED_LONG:
2151 jo_ar.reset( jni->NewIntArray( nElements ) );
2152 jni.ensure_no_exception();
2153 if (0 < nElements)
2155 jni->SetIntArrayRegion(
2156 static_cast<jintArray>(jo_ar.get()),
2157 0, nElements, reinterpret_cast<jint *>(seq->elements) );
2158 jni.ensure_no_exception();
2160 break;
2161 case typelib_TypeClass_HYPER:
2162 case typelib_TypeClass_UNSIGNED_HYPER:
2163 jo_ar.reset( jni->NewLongArray( nElements ) );
2164 jni.ensure_no_exception();
2165 if (0 < nElements)
2167 jni->SetLongArrayRegion(
2168 static_cast<jlongArray>(jo_ar.get()),
2169 0, nElements, reinterpret_cast<jlong *>(seq->elements) );
2170 jni.ensure_no_exception();
2172 break;
2173 case typelib_TypeClass_FLOAT:
2174 jo_ar.reset( jni->NewFloatArray( nElements ) );
2175 jni.ensure_no_exception();
2176 if (0 < nElements)
2178 jni->SetFloatArrayRegion(
2179 static_cast<jfloatArray>(jo_ar.get()),
2180 0, nElements, reinterpret_cast<jfloat *>(seq->elements) );
2181 jni.ensure_no_exception();
2183 break;
2184 case typelib_TypeClass_DOUBLE:
2185 jo_ar.reset( jni->NewDoubleArray( nElements ) );
2186 jni.ensure_no_exception();
2187 if (0 < nElements)
2189 jni->SetDoubleArrayRegion(
2190 static_cast<jdoubleArray>(jo_ar.get()),
2191 0, nElements, reinterpret_cast<jdouble *>(seq->elements) );
2192 jni.ensure_no_exception();
2194 break;
2195 case typelib_TypeClass_STRING:
2196 jo_ar.reset(
2197 jni->NewObjectArray(
2198 nElements, getJniInfo()->m_class_String, nullptr ) );
2199 jni.ensure_no_exception();
2200 if (in_param)
2202 rtl_uString * const * pp =
2203 reinterpret_cast<rtl_uString * const *>(seq->elements);
2204 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2206 JLocalAutoRef jo_string(
2207 jni, ustring_to_jstring( jni, pp[ nPos ] ) );
2208 jni->SetObjectArrayElement(
2209 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_string.get() );
2210 jni.ensure_no_exception();
2213 break;
2214 case typelib_TypeClass_TYPE:
2215 jo_ar.reset(
2216 jni->NewObjectArray( nElements, getJniInfo()->m_class_Type, nullptr ) );
2217 jni.ensure_no_exception();
2218 if (in_param)
2220 typelib_TypeDescriptionReference * const * pp =
2221 reinterpret_cast<typelib_TypeDescriptionReference * const *>(seq->elements);
2222 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2224 jvalue val;
2225 map_to_java(
2226 jni, &val, &pp[ nPos ], element_type, nullptr,
2227 true /* in */, false /* no out */ );
2228 JLocalAutoRef jo_element( jni, val.l );
2229 jni->SetObjectArrayElement(
2230 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2231 jni.ensure_no_exception();
2234 break;
2235 case typelib_TypeClass_ANY:
2236 jo_ar.reset(
2237 jni->NewObjectArray(
2238 nElements, getJniInfo()->m_class_Object, nullptr ) );
2239 jni.ensure_no_exception();
2240 if (in_param)
2242 uno_Any const * p = reinterpret_cast<uno_Any const *>(seq->elements);
2243 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2245 jvalue val;
2246 map_to_java(
2247 jni, &val, &p[ nPos ], element_type, nullptr,
2248 true /* in */, false /* no out */ );
2249 JLocalAutoRef jo_element( jni, val.l );
2250 jni->SetObjectArrayElement(
2251 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2252 jni.ensure_no_exception();
2255 break;
2256 case typelib_TypeClass_ENUM:
2258 OUString const & element_type_name =
2259 OUString::unacquired( &element_type->pTypeName );
2260 OString class_name(
2261 OUStringToOString(
2262 element_type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
2263 JLocalAutoRef jo_enum_class(
2264 jni, find_class( jni, class_name.getStr() ) );
2266 jo_ar.reset(
2267 jni->NewObjectArray(
2268 nElements, static_cast<jclass>(jo_enum_class.get()), nullptr ) );
2269 jni.ensure_no_exception();
2271 if (0 < nElements)
2273 // call static <enum_class>.fromInt( int )
2274 OString sig = "(I)L" + class_name.replace( '.', '/' ) + ";";
2275 jmethodID method_id = jni->GetStaticMethodID(
2276 static_cast<jclass>(jo_enum_class.get()), "fromInt", sig.getStr() );
2277 jni.ensure_no_exception();
2278 assert( method_id != nullptr );
2280 sal_Int32 const * p = reinterpret_cast<sal_Int32 const *>(seq->elements);
2281 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2283 jvalue arg;
2284 arg.i = p[ nPos ];
2285 JLocalAutoRef jo_enum(
2286 jni, jni->CallStaticObjectMethodA(
2287 static_cast<jclass>(jo_enum_class.get()), method_id, &arg ) );
2288 jni.ensure_no_exception();
2289 jni->SetObjectArrayElement(
2290 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_enum.get() );
2291 jni.ensure_no_exception();
2294 break;
2296 case typelib_TypeClass_STRUCT:
2297 case typelib_TypeClass_EXCEPTION:
2299 JNI_type_info const * element_info =
2300 getJniInfo()->get_type_info( jni, element_type );
2302 jo_ar.reset(
2303 jni->NewObjectArray( nElements, element_info->m_class, nullptr ) );
2304 jni.ensure_no_exception();
2306 if (0 < nElements)
2308 char * p = const_cast<char *>(seq->elements);
2309 sal_Int32 nSize = element_info->m_td.get()->nSize;
2310 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2312 jvalue val;
2313 map_to_java(
2314 jni, &val, p + (nSize * nPos),
2315 element_type, element_info,
2316 true /* in */, false /* no out */ );
2317 JLocalAutoRef jo_element( jni, val.l );
2318 jni->SetObjectArrayElement(
2319 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_element.get() );
2320 jni.ensure_no_exception();
2323 break;
2325 case typelib_TypeClass_SEQUENCE:
2327 OStringBuffer buf( 64 );
2328 JNI_info::append_sig(
2329 &buf, element_type, false /* use class XInterface */,
2330 false /* '.' instead of '/' */ );
2331 OString class_name( buf.makeStringAndClear() );
2332 JLocalAutoRef jo_seq_class(
2333 jni, find_class( jni, class_name.getStr() ) );
2335 jo_ar.reset(
2336 jni->NewObjectArray(
2337 nElements, static_cast<jclass>(jo_seq_class.get()), nullptr ) );
2338 jni.ensure_no_exception();
2340 if (0 < nElements)
2342 uno_Sequence * const * elements = reinterpret_cast<uno_Sequence * const *>(seq->elements);
2343 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2345 jvalue java_data2;
2346 map_to_java(
2347 jni, &java_data2, elements + nPos, element_type, nullptr,
2348 true /* in */, false /* no out */ );
2349 JLocalAutoRef jo_seq( jni, java_data2.l );
2350 jni->SetObjectArrayElement(
2351 static_cast<jobjectArray>(jo_ar.get()), nPos, jo_seq.get() );
2352 jni.ensure_no_exception();
2355 break;
2357 case typelib_TypeClass_INTERFACE:
2359 JNI_interface_type_info const * iface_info =
2360 static_cast< JNI_interface_type_info const * >(
2361 getJniInfo()->get_type_info( jni, element_type ) );
2363 jo_ar.reset(
2364 jni->NewObjectArray( nElements, iface_info->m_class, nullptr ) );
2365 jni.ensure_no_exception();
2367 if (0 < nElements)
2369 uno_Interface * const * pp = reinterpret_cast<uno_Interface * const *>(seq->elements);
2370 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2372 uno_Interface * pUnoI = pp[ nPos ];
2373 if (pUnoI != nullptr)
2375 JLocalAutoRef jo_element(
2376 jni, map_to_java( jni, pUnoI, iface_info ) );
2377 jni->SetObjectArrayElement(
2378 static_cast<jobjectArray>(jo_ar.get()),
2379 nPos, jo_element.get() );
2380 jni.ensure_no_exception();
2384 break;
2386 default:
2388 throw BridgeRuntimeError(
2389 "[map_to_java():" + OUString::unacquired( &type->pTypeName )
2390 + "] unsupported element type: "
2391 + OUString::unacquired( &element_type->pTypeName )
2392 + jni.get_stack_trace() );
2396 if (out_param)
2398 if (java_data->l == nullptr)
2400 JLocalAutoRef jo_element_class(
2401 jni, jni->GetObjectClass( jo_ar.get() ) );
2402 if (in_param)
2404 java_data->l = jni->NewObjectArray(
2405 1, static_cast<jclass>(jo_element_class.get()), jo_ar.get() );
2407 else
2409 java_data->l = jni->NewObjectArray(
2410 1, static_cast<jclass>(jo_element_class.get()), nullptr );
2412 jni.ensure_no_exception();
2414 else
2416 jni->SetObjectArrayElement(
2417 static_cast<jobjectArray>(java_data->l), 0, jo_ar.get() );
2418 jni.ensure_no_exception();
2421 else
2423 java_data->l = jo_ar.release();
2425 break;
2427 case typelib_TypeClass_INTERFACE:
2429 JLocalAutoRef jo_iface( jni );
2430 if (in_param)
2432 uno_Interface * pUnoI = *static_cast<uno_Interface * const *>(uno_data);
2433 if (pUnoI != nullptr)
2435 if (info == nullptr)
2436 info = getJniInfo()->get_type_info( jni, type );
2437 JNI_interface_type_info const * iface_info =
2438 static_cast< JNI_interface_type_info const * >( info );
2439 jo_iface.reset( map_to_java( jni, pUnoI, iface_info ) );
2442 if (out_param)
2444 if (java_data->l == nullptr)
2446 if (info == nullptr)
2447 info = getJniInfo()->get_type_info( jni, type );
2448 java_data->l =
2449 jni->NewObjectArray( 1, info->m_class, jo_iface.get() );
2450 jni.ensure_no_exception();
2452 else
2454 jni->SetObjectArrayElement(
2455 static_cast<jobjectArray>(java_data->l), 0, jo_iface.get() );
2456 jni.ensure_no_exception();
2459 else
2461 java_data->l = jo_iface.release();
2463 break;
2465 default:
2467 throw BridgeRuntimeError(
2468 "[map_to_java():" + OUString::unacquired( &type->pTypeName )
2469 + "] unsupported type!" + jni.get_stack_trace() );
2476 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */