LibreOffice Module bridges (master) 1
jni_data.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <cassert>
23#include <memory>
24
25#include "jni_bridge.h"
26
27#include <rtl/strbuf.hxx>
28#include <uno/sequence2.h>
29
30namespace jni_uno
31{
32
33
34static std::unique_ptr<rtl_mem> seq_allocate(
35 sal_Int32 nElements, sal_Int32 nSize )
36{
37 std::unique_ptr< rtl_mem > seq(
39 uno_Sequence * p = reinterpret_cast<uno_Sequence *>(seq.get());
40 p->nRefCount = 1;
41 p->nElements = nElements;
42 return seq;
43}
44
45
46namespace {
47
48void createDefaultUnoValue(
49 JNI_context const & jni, void * uno_data,
50 typelib_TypeDescriptionReference * type,
51 JNI_type_info const * info /* maybe 0 */, bool assign)
52{
53 switch (type->eTypeClass) {
54 case typelib_TypeClass_BOOLEAN:
55 *static_cast< sal_Bool * >(uno_data) = false;
56 break;
57
58 case typelib_TypeClass_BYTE:
59 *static_cast< sal_Int8 * >(uno_data) = 0;
60 break;
61
62 case typelib_TypeClass_SHORT:
63 *static_cast< sal_Int16 * >(uno_data) = 0;
64 break;
65
66 case typelib_TypeClass_UNSIGNED_SHORT:
67 *static_cast< sal_uInt16 * >(uno_data) = 0;
68 break;
69
70 case typelib_TypeClass_LONG:
71 *static_cast< sal_Int32 * >(uno_data) = 0;
72 break;
73
74 case typelib_TypeClass_UNSIGNED_LONG:
75 *static_cast< sal_uInt32 * >(uno_data) = 0;
76 break;
77
78 case typelib_TypeClass_HYPER:
79 *static_cast< sal_Int64 * >(uno_data) = 0;
80 break;
81
82 case typelib_TypeClass_UNSIGNED_HYPER:
83 *static_cast< sal_uInt64 * >(uno_data) = 0;
84 break;
85
86 case typelib_TypeClass_FLOAT:
87 *static_cast< float * >(uno_data) = 0;
88 break;
89
90 case typelib_TypeClass_DOUBLE:
91 *static_cast< double * >(uno_data) = 0;
92 break;
93
94 case typelib_TypeClass_CHAR:
95 *static_cast< sal_Unicode * >(uno_data) = 0;
96 break;
97
98 case typelib_TypeClass_STRING:
99 if (!assign) {
100 *static_cast< rtl_uString ** >(uno_data) = nullptr;
101 }
102 rtl_uString_new(static_cast< rtl_uString ** >(uno_data));
103 break;
104
105 case typelib_TypeClass_TYPE:
106 if (assign) {
108 *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
109 }
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);
115 *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
116 break;
117
118 case typelib_TypeClass_ANY:
119 if (assign) {
120 uno_any_destruct(static_cast< uno_Any * >(uno_data), nullptr);
121 }
123 static_cast< uno_Any * >(uno_data), nullptr,
124 jni.get_info()->m_XInterface_type_info->m_td.get(), nullptr);
125 break;
126
127 case typelib_TypeClass_SEQUENCE:
128 {
129 std::unique_ptr< rtl_mem > seq(seq_allocate(0, 0));
130 if (assign) {
131 uno_type_destructData(uno_data, type, nullptr);
132 }
133 *static_cast< uno_Sequence ** >(uno_data)
134 = reinterpret_cast< uno_Sequence * >(seq.release());
135 break;
136 }
137
138 case typelib_TypeClass_ENUM:
139 {
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;
147 }
148
149 case typelib_TypeClass_STRUCT:
150 {
151 if (info == nullptr) {
152 info = jni.get_info()->get_type_info(jni, type);
153 }
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);
167 }
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);
174 }
175 } catch (...) {
176 if (!assign) {
177 for (sal_Int32 i = 0; i < nPos; ++i) {
179 (static_cast< char * >(uno_data)
180 + comp_td->pMemberOffsets[i]),
181 comp_td->ppTypeRefs[i], nullptr);
182 }
183 if (comp_td->pBaseTypeDescription != nullptr) {
185 uno_data, &comp_td->pBaseTypeDescription->aBase, nullptr);
186 }
187 }
188 throw;
189 }
190 }
191 break;
192
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);
198 }
199 }
200 *static_cast< uno_Interface ** >(uno_data) = nullptr;
201 break;
202
203 default:
204 assert(false);
205 break;
206 }
207}
208
209}
210
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
218{
219 assert(
220 !out_param ||
221 (jni->GetArrayLength( static_cast<jarray>(java_data.l) ) == 1) );
222
223 switch (type->eTypeClass)
224 {
225 case typelib_TypeClass_CHAR:
226 if (out_param)
227 {
228 jni->GetCharArrayRegion(
229 static_cast<jcharArray>(java_data.l), 0, 1, static_cast<jchar *>(uno_data) );
231 }
232 else if (special_wrapped_integral_types)
233 {
234 *static_cast<jchar *>(uno_data) = jni->CallCharMethodA(
235 java_data.l, getJniInfo()->m_method_Character_charValue, nullptr );
237 }
238 else
239 {
240 *static_cast<jchar *>(uno_data) = java_data.c;
241 }
242 break;
243 case typelib_TypeClass_BOOLEAN:
244 if (out_param)
245 {
246 jni->GetBooleanArrayRegion(
247 static_cast<jbooleanArray>(java_data.l), 0, 1, static_cast<jboolean *>(uno_data) );
249 }
250 else if (special_wrapped_integral_types)
251 {
252 *static_cast<jboolean *>(uno_data) = jni->CallBooleanMethodA(
253 java_data.l, getJniInfo()->m_method_Boolean_booleanValue, nullptr );
255 }
256 else
257 {
258 *static_cast<jboolean *>(uno_data) = java_data.z;
259 }
260 break;
261 case typelib_TypeClass_BYTE:
262 if (out_param)
263 {
264 jni->GetByteArrayRegion(
265 static_cast<jbyteArray>(java_data.l), 0, 1, static_cast<jbyte *>(uno_data) );
267 }
268 else if (special_wrapped_integral_types)
269 {
270 *static_cast<jbyte *>(uno_data) = jni->CallByteMethodA(
271 java_data.l, getJniInfo()->m_method_Byte_byteValue, nullptr );
273 }
274 else
275 {
276 *static_cast<jbyte *>(uno_data) = java_data.b;
277 }
278 break;
279 case typelib_TypeClass_SHORT:
280 case typelib_TypeClass_UNSIGNED_SHORT:
281 if (out_param)
282 {
283 jni->GetShortArrayRegion(
284 static_cast<jshortArray>(java_data.l), 0, 1, static_cast<jshort *>(uno_data) );
286 }
287 else if (special_wrapped_integral_types)
288 {
289 *static_cast<jshort *>(uno_data) = jni->CallShortMethodA(
290 java_data.l, getJniInfo()->m_method_Short_shortValue, nullptr );
292 }
293 else
294 {
295 *static_cast<jshort *>(uno_data) = java_data.s;
296 }
297 break;
298 case typelib_TypeClass_LONG:
299 case typelib_TypeClass_UNSIGNED_LONG:
300 if (out_param)
301 {
302 jni->GetIntArrayRegion(
303 static_cast<jintArray>(java_data.l), 0, 1, static_cast<jint *>(uno_data) );
305 }
306 else if (special_wrapped_integral_types)
307 {
308 *static_cast<jint *>(uno_data) = jni->CallIntMethodA(
309 java_data.l, getJniInfo()->m_method_Integer_intValue, nullptr );
311 }
312 else
313 {
314 *static_cast<jint *>(uno_data) = java_data.i;
315 }
316 break;
317 case typelib_TypeClass_HYPER:
318 case typelib_TypeClass_UNSIGNED_HYPER:
319 if (out_param)
320 {
321 jni->GetLongArrayRegion(
322 static_cast<jlongArray>(java_data.l), 0, 1, static_cast<jlong *>(uno_data) );
324 }
325 else if (special_wrapped_integral_types)
326 {
327 *static_cast<jlong *>(uno_data) = jni->CallLongMethodA(
328 java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
330 }
331 else
332 {
333 *static_cast<jlong *>(uno_data) = java_data.j;
334 }
335 break;
336 case typelib_TypeClass_FLOAT:
337 if (out_param)
338 {
339 jni->GetFloatArrayRegion(
340 static_cast<jfloatArray>(java_data.l), 0, 1, static_cast<jfloat *>(uno_data) );
342 }
343 else if (special_wrapped_integral_types)
344 {
345 *static_cast<jfloat *>(uno_data) = jni->CallFloatMethodA(
346 java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
348 }
349 else
350 {
351 *static_cast<jfloat *>(uno_data) = java_data.f;
352 }
353 break;
354 case typelib_TypeClass_DOUBLE:
355 if (out_param)
356 {
357 jni->GetDoubleArrayRegion(
358 static_cast<jdoubleArray>(java_data.l), 0, 1, static_cast<jdouble *>(uno_data) );
360 }
361 else if (special_wrapped_integral_types)
362 {
363 *static_cast<jdouble *>(uno_data) = jni->CallDoubleMethodA(
364 java_data.l, getJniInfo()->m_method_Double_doubleValue, nullptr );
366 }
367 else
368 {
369 *static_cast<jdouble *>(uno_data) = java_data.d;
370 }
371 break;
372 case typelib_TypeClass_STRING:
373 {
374 JLocalAutoRef jo_out_holder( jni );
375 if (out_param)
376 {
377 jo_out_holder.reset(
378 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
380 java_data.l = jo_out_holder.get();
381 }
382 if (java_data.l == nullptr)
383 {
384 throw BridgeRuntimeError(
385 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
386 + "] null-ref given!" + jni.get_stack_trace() );
387 }
388 if (! assign)
389 *static_cast<rtl_uString **>(uno_data) = nullptr;
391 jni, static_cast<rtl_uString **>(uno_data), static_cast<jstring>(java_data.l) );
392 break;
393 }
394 case typelib_TypeClass_TYPE:
395 {
396 JLocalAutoRef jo_out_holder( jni );
397 if (out_param)
398 {
399 jo_out_holder.reset(
400 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
402 java_data.l = jo_out_holder.get();
403 }
404 if (java_data.l == nullptr)
405 {
406 throw BridgeRuntimeError(
407 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
408 + "] null-ref given!" + jni.get_stack_trace() );
409 }
410
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())
416 {
417 throw BridgeRuntimeError(
418 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
419 + "] incomplete type object: no type name!"
420 + jni.get_stack_trace() );
421 }
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())
426 {
427 throw BridgeRuntimeError(
428 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
429 + "] UNO type not found: " + type_name
430 + jni.get_stack_trace() );
431 }
432 typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
433 if (assign)
434 {
436 *static_cast<typelib_TypeDescriptionReference **>(uno_data) );
437 }
438 *static_cast<typelib_TypeDescriptionReference **>(uno_data) = td.get()->pWeakRef;
439 break;
440 }
441 case typelib_TypeClass_ANY:
442 {
443 JLocalAutoRef jo_out_holder( jni );
444 if (out_param)
445 {
446 jo_out_holder.reset(
447 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
449 java_data.l = jo_out_holder.get();
450 }
451
452 uno_Any * pAny = static_cast<uno_Any *>(uno_data);
453 if (java_data.l == nullptr) // null-ref maps to XInterface null-ref
454 {
455 if (assign)
456 uno_any_destruct( pAny, nullptr );
458 pAny, nullptr, getJniInfo()->m_XInterface_type_info->m_td.get(), nullptr );
459 break;
460 }
461
462 JLocalAutoRef jo_type( jni );
463 JLocalAutoRef jo_wrapped_holder( jni );
464
465 if (jni->IsInstanceOf( java_data.l, getJniInfo()->m_class_Any ))
466 {
467 // boxed any
468 jo_type.reset( jni->GetObjectField(
469 java_data.l, getJniInfo()->m_field_Any_type ) );
470 if (! jo_type.is())
471 {
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() );
476 }
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();
482 }
483 else
484 {
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()) ) );
488 }
489
490 // get type name
491 JLocalAutoRef jo_type_name(
492 jni, jni->GetObjectField(
493 jo_type.get(), getJniInfo()->m_field_Type_typeName ) );
495 OUString type_name(
496 jstring_to_oustring( jni, static_cast<jstring>(jo_type_name.get()) ) );
497
498 ::com::sun::star::uno::TypeDescription value_td( type_name );
499 if (! value_td.is())
500 {
501 throw BridgeRuntimeError(
502 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
503 + "] UNO type not found: " + type_name
504 + jni.get_stack_trace() );
505 }
506 typelib_TypeClass type_class = value_td.get()->eTypeClass;
507
508 if (assign)
509 {
510 uno_any_destruct( pAny, nullptr );
511 }
512 try
513 {
514 switch (type_class)
515 {
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 );
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 );
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 );
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 );
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 );
550 break;
551 case typelib_TypeClass_HYPER:
552 case typelib_TypeClass_UNSIGNED_HYPER:
553 if (sizeof (sal_Int64) <= sizeof (void *))
554 {
555 pAny->pData = &pAny->pReserved;
556 *static_cast<jlong *>(pAny->pData) = jni->CallLongMethodA(
557 java_data.l, getJniInfo()->m_method_Long_longValue, nullptr );
559 }
560 else
561 {
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 );
567 pAny->pData = mem.release();
568 }
569 break;
570 case typelib_TypeClass_FLOAT:
571 if (sizeof (float) <= sizeof (void *))
572 {
573 pAny->pData = &pAny->pReserved;
574 *static_cast<jfloat *>(pAny->pData) = jni->CallFloatMethodA(
575 java_data.l, getJniInfo()->m_method_Float_floatValue, nullptr );
577 }
578 else
579 {
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 );
585 pAny->pData = mem.release();
586 }
587 break;
588 case typelib_TypeClass_DOUBLE:
589 if (sizeof (double) <= sizeof (void *))
590 {
591 pAny->pData = &pAny->pReserved;
592 *static_cast<jdouble *>(pAny->pData) =
593 jni->CallDoubleMethodA(
594 java_data.l,
597 }
598 else
599 {
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,
607 pAny->pData = mem.release();
608 }
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;
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;
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:
630 {
631 std::unique_ptr< rtl_mem > mem(
632 rtl_mem::allocate( value_td.get()->nSize ) );
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;
638 }
639 default:
640 {
641 throw BridgeRuntimeError(
642 "[map_to_uno():" + type_name
643 + "] unsupported value type of any!"
644 + jni.get_stack_trace() );
645 }
646 }
647 }
648 catch (...)
649 {
650 if (assign)
651 {
652 // restore to valid any
653 uno_any_construct( pAny, nullptr, nullptr, nullptr );
654 }
655 throw;
656 }
657 typelib_typedescriptionreference_acquire( value_td.get()->pWeakRef );
658 pAny->pType = value_td.get()->pWeakRef;
659 break;
660 }
661 case typelib_TypeClass_ENUM:
662 {
663 JLocalAutoRef jo_out_holder( jni );
664 if (out_param)
665 {
666 jo_out_holder.reset(
667 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
669 java_data.l = jo_out_holder.get();
670 }
671 if (java_data.l == nullptr)
672 {
673 throw BridgeRuntimeError(
674 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
675 + "] null-ref given!" + jni.get_stack_trace() );
676 }
677
678 *static_cast<jint *>(uno_data) = jni->GetIntField(
679 java_data.l, getJniInfo()->m_field_Enum_m_value );
680 break;
681 }
682 case typelib_TypeClass_STRUCT:
683 case typelib_TypeClass_EXCEPTION:
684 {
685 JLocalAutoRef jo_out_holder( jni );
686 if (out_param)
687 {
688 jo_out_holder.reset(
689 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
691 java_data.l = jo_out_holder.get();
692 }
693 if (java_data.l == nullptr)
694 {
695 throw BridgeRuntimeError(
696 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
697 + "] null-ref given!" + jni.get_stack_trace() );
698 }
699
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 );
704
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;
711
712 sal_Int32 nPos = 0;
713 sal_Int32 nMembers = comp_td->nMembers;
714 try
715 {
716 if (comp_td->pBaseTypeDescription != nullptr)
717 {
719 jni, uno_data, java_data,
720 comp_td->pBaseTypeDescription->aBase.pWeakRef,
721 comp_info->m_base,
722 assign, false /* no out param */ );
723 }
724
725 for ( ; nPos < nMembers; ++nPos )
726 {
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)
735 {
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();
746 jni, p, val, member_type, nullptr, assign, false,
747 true );
748 }
749 } else {
750 *static_cast<jchar *>(p) = jni->GetCharField(
751 java_data.l, field_id );
752 }
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();
764 jni, p, val, member_type, nullptr, assign, false,
765 true );
766 }
767 } else {
768 *static_cast<jboolean *>(p) = jni->GetBooleanField(
769 java_data.l, field_id );
770 }
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();
782 jni, p, val, member_type, nullptr, assign, false,
783 true );
784 }
785 } else {
786 *static_cast<jbyte *>(p) = jni->GetByteField(
787 java_data.l, field_id );
788 }
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();
801 jni, p, val, member_type, nullptr, assign, false,
802 true );
803 }
804 } else {
805 *static_cast<jshort *>(p) = jni->GetShortField(
806 java_data.l, field_id );
807 }
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();
820 jni, p, val, member_type, nullptr, assign, false,
821 true );
822 }
823 } else {
824 *static_cast<jint *>(p) = jni->GetIntField( java_data.l, field_id );
825 }
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();
838 jni, p, val, member_type, nullptr, assign, false,
839 true );
840 }
841 } else {
842 *static_cast<jlong *>(p) = jni->GetLongField(
843 java_data.l, field_id );
844 }
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();
856 jni, p, val, member_type, nullptr, assign, false,
857 true );
858 }
859 } else {
860 *static_cast<jfloat *>(p) = jni->GetFloatField(
861 java_data.l, field_id );
862 }
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();
874 jni, p, val, member_type, nullptr, assign, false,
875 true );
876 }
877 } else {
878 *static_cast<jdouble *>(p) = jni->GetDoubleField(
879 java_data.l, field_id );
880 }
881 break;
882 default:
883 {
884 JLocalAutoRef jo_field( jni );
885 bool checkNull;
886 if (field_id == nullptr)
887 {
888 // special for Message: call Throwable.getMessage()
889 assert(
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 )
903 );
905 checkNull = true;
906 }
907 else
908 {
909 jo_field.reset(
910 jni->GetObjectField( java_data.l, field_id ) );
911 checkNull = parameterizedType;
912 }
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();
919 jni, p, val, member_type, nullptr,
920 assign, false /* no out param */ );
921 }
922 break;
923 }
924 }
925 }
926 }
927 catch (...)
928 {
929 if (! assign)
930 {
931 // cleanup
932 for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
933 {
934 void * p =
935 static_cast<char *>(uno_data) + comp_td->pMemberOffsets[ nCleanup ];
937 p, comp_td->ppTypeRefs[ nCleanup ], nullptr );
938 }
939 if (comp_td->pBaseTypeDescription != nullptr)
940 {
942 uno_data, &comp_td->pBaseTypeDescription->aBase, nullptr );
943 }
944 }
945 throw;
946 }
947 break;
948 }
949 case typelib_TypeClass_SEQUENCE:
950 {
951 JLocalAutoRef jo_out_holder( jni );
952 if (out_param)
953 {
954 jo_out_holder.reset(
955 jni->GetObjectArrayElement( static_cast<jobjectArray>(java_data.l), 0 ) );
957 java_data.l = jo_out_holder.get();
958 }
959 if (java_data.l == nullptr)
960 {
961 throw BridgeRuntimeError(
962 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
963 + "] null-ref given!" + jni.get_stack_trace() );
964 }
965
966 TypeDescr td( type );
967 typelib_TypeDescriptionReference * element_type =
968 reinterpret_cast<typelib_IndirectTypeDescription *>(td.get())->pType;
969
970 std::unique_ptr< rtl_mem > seq;
971 sal_Int32 nElements = jni->GetArrayLength( static_cast<jarray>(java_data.l) );
972
973 switch (element_type->eTypeClass)
974 {
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) );
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) );
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) );
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:
1042 {
1043 TypeDescr element_td( element_type );
1044 seq = seq_allocate( nElements, element_td.get()->nSize );
1045
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)
1050 {
1051 element_info =
1052 getJniInfo()->get_type_info( jni, element_td.get() );
1053 }
1054 else
1055 {
1056 element_info = nullptr;
1057 }
1058
1059 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
1060 {
1061 try
1062 {
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 */ );
1075 }
1076 catch (...)
1077 {
1078 // cleanup
1079 for ( sal_Int32 nCleanPos = 0;
1080 nCleanPos < nPos; ++nCleanPos )
1081 {
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 );
1086 }
1087 throw;
1088 }
1089 }
1090 break;
1091 }
1092 default:
1093 {
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() );
1099 }
1100 }
1101
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;
1106 }
1107 case typelib_TypeClass_INTERFACE:
1108 {
1109 JLocalAutoRef jo_out_holder( jni );
1110 if (out_param)
1111 {
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();
1116 }
1117
1118 if (java_data.l == nullptr) // null-ref
1119 {
1120 if (assign)
1121 {
1122 uno_Interface * p = *static_cast<uno_Interface **>(uno_data);
1123 if (p != nullptr)
1124 (*p->release)( p );
1125 }
1126 *static_cast<uno_Interface **>(uno_data) = nullptr;
1127 }
1128 else
1129 {
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)
1136 {
1137 uno_Interface * p = *static_cast<uno_Interface **>(uno_data);
1138 if (p != nullptr)
1139 (*p->release)( p );
1140 }
1141 *static_cast<uno_Interface **>(uno_data) = pUnoI;
1142 }
1143 break;
1144 }
1145 default:
1146 {
1147 throw BridgeRuntimeError(
1148 "[map_to_uno():" + OUString::unacquired( &type->pTypeName )
1149 + "] unsupported type!" + jni.get_stack_trace() );
1150 }
1151 }
1152}
1153
1154
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
1162{
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);
1169
1170 switch (type->eTypeClass)
1171 {
1172 case typelib_TypeClass_CHAR:
1173 if (out_param)
1174 {
1175 if (java_data->l == nullptr)
1176 {
1177 JLocalAutoRef jo_ar( jni, jni->NewCharArray( 1 ) );
1178 jni.ensure_no_exception();
1179 if (in_param)
1180 {
1181 jni->SetCharArrayRegion(
1182 static_cast<jcharArray>(jo_ar.get()), 0, 1, static_cast<jchar *>(data) );
1183 jni.ensure_no_exception();
1184 }
1185 java_data->l = jo_ar.release();
1186 }
1187 else
1188 {
1189 if (in_param)
1190 {
1191 jni->SetCharArrayRegion(
1192 static_cast<jcharArray>(java_data->l), 0, 1, static_cast<jchar *>(data) );
1193 jni.ensure_no_exception();
1194 }
1195 }
1196 }
1197 else if (special_wrapped_integral_types)
1198 {
1199 jvalue arg;
1200 arg.c = *static_cast<jchar const *>(uno_data);
1201 java_data->l = jni->NewObjectA(
1204 jni.ensure_no_exception();
1205 }
1206 else
1207 {
1208 java_data->c = *static_cast<jchar const *>(uno_data);
1209 }
1210 break;
1211 case typelib_TypeClass_BOOLEAN:
1212 if (out_param)
1213 {
1214 if (java_data->l == nullptr)
1215 {
1216 JLocalAutoRef jo_ar( jni, jni->NewBooleanArray( 1 ) );
1217 jni.ensure_no_exception();
1218 if (in_param)
1219 {
1220 jni->SetBooleanArrayRegion(
1221 static_cast<jbooleanArray>(jo_ar.get()),
1222 0, 1, static_cast<jboolean *>(data) );
1223 jni.ensure_no_exception();
1224 }
1225 java_data->l = jo_ar.release();
1226 }
1227 else
1228 {
1229 if (in_param)
1230 {
1231 jni->SetBooleanArrayRegion(
1232 static_cast<jbooleanArray>(java_data->l),
1233 0, 1, static_cast<jboolean *>(data) );
1234 jni.ensure_no_exception();
1235 }
1236 }
1237 }
1238 else if (special_wrapped_integral_types)
1239 {
1240 jvalue arg;
1241 arg.z = *static_cast<jboolean const *>(uno_data);
1242 java_data->l = jni->NewObjectA(
1245 jni.ensure_no_exception();
1246 }
1247 else
1248 {
1249 java_data->z = *static_cast<jboolean const *>(uno_data);
1250 }
1251 break;
1252 case typelib_TypeClass_BYTE:
1253 if (out_param)
1254 {
1255 if (java_data->l == nullptr)
1256 {
1257 JLocalAutoRef jo_ar( jni, jni->NewByteArray( 1 ) );
1258 jni.ensure_no_exception();
1259 if (in_param)
1260 {
1261 jni->SetByteArrayRegion(
1262 static_cast<jbyteArray>(jo_ar.get()), 0, 1, static_cast<jbyte *>(data) );
1263 jni.ensure_no_exception();
1264 }
1265 java_data->l = jo_ar.release();
1266 }
1267 else
1268 {
1269 if (in_param)
1270 {
1271 jni->SetByteArrayRegion(
1272 static_cast<jbyteArray>(java_data->l), 0, 1, static_cast<jbyte *>(data) );
1273 jni.ensure_no_exception();
1274 }
1275 }
1276 }
1277 else if (special_wrapped_integral_types)
1278 {
1279 jvalue arg;
1280 arg.b = *static_cast<jbyte const *>(uno_data);
1281 java_data->l = jni->NewObjectA(
1284 jni.ensure_no_exception();
1285 }
1286 else
1287 {
1288 java_data->b = *static_cast<jbyte const *>(uno_data);
1289 }
1290 break;
1291 case typelib_TypeClass_SHORT:
1292 case typelib_TypeClass_UNSIGNED_SHORT:
1293 if (out_param)
1294 {
1295 if (java_data->l == nullptr)
1296 {
1297 JLocalAutoRef jo_ar( jni, jni->NewShortArray( 1 ) );
1298 jni.ensure_no_exception();
1299 if (in_param)
1300 {
1301 jni->SetShortArrayRegion(
1302 static_cast<jshortArray>(jo_ar.get()), 0, 1, static_cast<jshort *>(data) );
1303 jni.ensure_no_exception();
1304 }
1305 java_data->l = jo_ar.release();
1306 }
1307 else
1308 {
1309 if (in_param)
1310 {
1311 jni->SetShortArrayRegion(
1312 static_cast<jshortArray>(java_data->l), 0, 1, static_cast<jshort *>(data) );
1313 jni.ensure_no_exception();
1314 }
1315 }
1316 }
1317 else if (special_wrapped_integral_types)
1318 {
1319 jvalue arg;
1320 arg.s = *static_cast<jshort const *>(uno_data);
1321 java_data->l = jni->NewObjectA(
1324 jni.ensure_no_exception();
1325 }
1326 else
1327 {
1328 java_data->s = *static_cast<jshort const *>(uno_data);
1329 }
1330 break;
1331 case typelib_TypeClass_LONG:
1332 case typelib_TypeClass_UNSIGNED_LONG:
1333 if (out_param)
1334 {
1335 if (java_data->l == nullptr)
1336 {
1337 JLocalAutoRef jo_ar( jni, jni->NewIntArray( 1 ) );
1338 jni.ensure_no_exception();
1339 if (in_param)
1340 {
1341 jni->SetIntArrayRegion(
1342 static_cast<jintArray>(jo_ar.get()), 0, 1, static_cast<jint *>(data) );
1343 jni.ensure_no_exception();
1344 }
1345 java_data->l = jo_ar.release();
1346 }
1347 else
1348 {
1349 if (in_param)
1350 {
1351 jni->SetIntArrayRegion(
1352 static_cast<jintArray>(java_data->l), 0, 1, static_cast<jint *>(data) );
1353 jni.ensure_no_exception();
1354 }
1355 }
1356 }
1357 else if (special_wrapped_integral_types)
1358 {
1359 jvalue arg;
1360 arg.i = *static_cast<jint const *>(uno_data);
1361 java_data->l = jni->NewObjectA(
1364 jni.ensure_no_exception();
1365 }
1366 else
1367 {
1368 java_data->i = *static_cast<jint const *>(uno_data);
1369 }
1370 break;
1371 case typelib_TypeClass_HYPER:
1372 case typelib_TypeClass_UNSIGNED_HYPER:
1373 if (out_param)
1374 {
1375 if (java_data->l == nullptr)
1376 {
1377 JLocalAutoRef jo_ar( jni, jni->NewLongArray( 1 ) );
1378 jni.ensure_no_exception();
1379 if (in_param)
1380 {
1381 jni->SetLongArrayRegion(
1382 static_cast<jlongArray>(jo_ar.get()), 0, 1, static_cast<jlong *>(data) );
1383 jni.ensure_no_exception();
1384 }
1385 java_data->l = jo_ar.release();
1386 }
1387 else
1388 {
1389 if (in_param)
1390 {
1391 jni->SetLongArrayRegion(
1392 static_cast<jlongArray>(java_data->l), 0, 1, static_cast<jlong *>(data) );
1393 jni.ensure_no_exception();
1394 }
1395 }
1396 }
1397 else if (special_wrapped_integral_types)
1398 {
1399 jvalue arg;
1400 arg.j = *static_cast<jlong const *>(uno_data);
1401 java_data->l = jni->NewObjectA(
1404 jni.ensure_no_exception();
1405 }
1406 else
1407 {
1408 java_data->j = *static_cast<jlong const *>(uno_data);
1409 }
1410 break;
1411 case typelib_TypeClass_FLOAT:
1412 if (out_param)
1413 {
1414 if (java_data->l == nullptr)
1415 {
1416 JLocalAutoRef jo_ar( jni, jni->NewFloatArray( 1 ) );
1417 jni.ensure_no_exception();
1418 if (in_param)
1419 {
1420 jni->SetFloatArrayRegion(
1421 static_cast<jfloatArray>(jo_ar.get()), 0, 1, static_cast<jfloat *>(data) );
1422 jni.ensure_no_exception();
1423 }
1424 java_data->l = jo_ar.release();
1425 }
1426 else
1427 {
1428 if (in_param)
1429 {
1430 jni->SetFloatArrayRegion(
1431 static_cast<jfloatArray>(java_data->l), 0, 1, static_cast<jfloat *>(data) );
1432 jni.ensure_no_exception();
1433 }
1434 }
1435 }
1436 else if (special_wrapped_integral_types)
1437 {
1438 jvalue arg;
1439 arg.f = *static_cast<jfloat const *>(uno_data);
1440 java_data->l = jni->NewObjectA(
1443 jni.ensure_no_exception();
1444 }
1445 else
1446 {
1447 java_data->f = *static_cast<jfloat const *>(uno_data);
1448 }
1449 break;
1450 case typelib_TypeClass_DOUBLE:
1451 if (out_param)
1452 {
1453 if (java_data->l == nullptr)
1454 {
1455 JLocalAutoRef jo_ar( jni, jni->NewDoubleArray( 1 ) );
1456 jni.ensure_no_exception();
1457 if (in_param)
1458 {
1459 jni->SetDoubleArrayRegion(
1460 static_cast<jdoubleArray>(jo_ar.get()),
1461 0, 1, static_cast<jdouble *>(data) );
1462 jni.ensure_no_exception();
1463 }
1464 java_data->l = jo_ar.release();
1465 }
1466 else
1467 {
1468 if (in_param)
1469 {
1470 jni->SetDoubleArrayRegion(
1471 static_cast<jdoubleArray>(java_data->l),
1472 0, 1, static_cast<jdouble *>(data) );
1473 jni.ensure_no_exception();
1474 }
1475 }
1476 }
1477 else if (special_wrapped_integral_types)
1478 {
1479 jvalue arg;
1480 arg.d = *static_cast<double const *>(uno_data);
1481 java_data->l = jni->NewObjectA(
1484 jni.ensure_no_exception();
1485 }
1486 else
1487 {
1488 java_data->d = *static_cast<jdouble const *>(uno_data);
1489 }
1490 break;
1491 case typelib_TypeClass_STRING:
1492 {
1493 if (out_param)
1494 {
1495 JLocalAutoRef jo_in( jni );
1496 if (in_param)
1497 {
1498 jo_in.reset(
1500 jni, *static_cast<rtl_uString * const *>(uno_data) ) );
1501 }
1502 if (java_data->l == nullptr)
1503 {
1504 java_data->l = jni->NewObjectArray(
1505 1, getJniInfo()->m_class_String, jo_in.get() );
1506 jni.ensure_no_exception();
1507 }
1508 else
1509 {
1510 jni->SetObjectArrayElement(
1511 static_cast<jobjectArray>(java_data->l), 0, jo_in.get() );
1512 jni.ensure_no_exception();
1513 }
1514 }
1515 else
1516 {
1517 assert( in_param );
1518 java_data->l =
1519 ustring_to_jstring( jni, *static_cast<rtl_uString * const *>(uno_data) );
1520 }
1521 break;
1522 }
1523 case typelib_TypeClass_TYPE:
1524 {
1525 if (out_param)
1526 {
1527 JLocalAutoRef jo_in( jni );
1528 if (in_param)
1529 {
1530 jo_in.reset(
1532 jni,
1533 *static_cast<typelib_TypeDescriptionReference * const *>(uno_data) )
1534 );
1535 }
1536 if (java_data->l == nullptr)
1537 {
1538 java_data->l = jni->NewObjectArray(
1539 1, getJniInfo()->m_class_Type, jo_in.get() );
1540 jni.ensure_no_exception();
1541 }
1542 else
1543 {
1544 jni->SetObjectArrayElement(
1545 static_cast<jobjectArray>(java_data->l), 0, jo_in.get() );
1546 jni.ensure_no_exception();
1547 }
1548 }
1549 else
1550 {
1551 assert( in_param );
1552 java_data->l =
1554 jni,
1555 *static_cast<typelib_TypeDescriptionReference * const *>(uno_data) );
1556 }
1557 break;
1558 }
1559 case typelib_TypeClass_ANY:
1560 {
1561 JLocalAutoRef jo_any( jni );
1562 if (in_param)
1563 {
1564 uno_Any const * pAny = static_cast<uno_Any const *>(uno_data);
1565 switch (pAny->pType->eTypeClass)
1566 {
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:
1572 {
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
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;
1589 }
1590 case typelib_TypeClass_UNSIGNED_LONG:
1591 {
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
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;
1608 }
1609 case typelib_TypeClass_UNSIGNED_HYPER:
1610 {
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
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;
1627 }
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:
1633 {
1634 jvalue java_data2;
1635 // prefetch sequence td
1636 TypeDescr seq_td( pAny->pType );
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 );
1642
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)
1648 {
1649 TypeDescr element_td( element_type.getTypeLibType() );
1651 reinterpret_cast< typelib_TypeDescriptionReference ** >(
1652 &element_type ),
1653 reinterpret_cast<typelib_IndirectTypeDescription *>(element_td.get())
1654 ->pType );
1655 }
1656 // box up only if unsigned element type
1657 switch (element_type.getTypeLibType()->eTypeClass)
1658 {
1659 case typelib_TypeClass_UNSIGNED_SHORT:
1660 case typelib_TypeClass_UNSIGNED_LONG:
1661 case typelib_TypeClass_UNSIGNED_HYPER:
1662 {
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;
1674 }
1675 default:
1676 break;
1677 }
1678 break;
1679 }
1680 case typelib_TypeClass_INTERFACE:
1681 {
1682 uno_Interface * pUnoI = static_cast<uno_Interface *>(pAny->pReserved);
1683 if (is_XInterface( pAny->pType ))
1684 {
1685 if (pUnoI != nullptr)
1686 {
1687 jo_any.reset(
1689 jni, pUnoI,
1690 getJniInfo()->m_XInterface_type_info ) );
1691 }
1692 // else: empty XInterface ref maps to null-ref
1693 }
1694 else
1695 {
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)
1700 {
1701 jo_any.reset( map_to_java( jni, pUnoI, iface_info ) );
1702 }
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();
1712 }
1713 break;
1714 }
1715 case typelib_TypeClass_STRUCT:
1716 {
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] == '>')
1723 {
1724 // Box up in com.sun.star.uno.Any:
1725 JLocalAutoRef jo_type(jni, create_type(jni, pAny->pType));
1726 jvalue java_data2;
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;
1740 }
1741 [[fallthrough]];
1742 }
1743 default:
1744 {
1745 jvalue java_data2;
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;
1752 }
1753 }
1754 }
1755
1756 if (out_param)
1757 {
1758 if (java_data->l == nullptr)
1759 {
1760 java_data->l = jni->NewObjectArray(
1761 1, getJniInfo()->m_class_Object, jo_any.get() );
1762 jni.ensure_no_exception();
1763 }
1764 else
1765 {
1766 jni->SetObjectArrayElement(
1767 static_cast<jobjectArray>(java_data->l), 0, jo_any.get() );
1768 jni.ensure_no_exception();
1769 }
1770 }
1771 else
1772 {
1773 java_data->l = jo_any.release();
1774 }
1775 break;
1776 }
1777 case typelib_TypeClass_ENUM:
1778 {
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() ) );
1784
1785 JLocalAutoRef jo_enum( jni );
1786 if (in_param)
1787 {
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 );
1794
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();
1801 }
1802 if (out_param)
1803 {
1804 if (java_data->l == nullptr)
1805 {
1806 java_data->l = jni->NewObjectArray(
1807 1, static_cast<jclass>(jo_enum_class.get()), jo_enum.get() );
1808 jni.ensure_no_exception();
1809 }
1810 else
1811 {
1812 jni->SetObjectArrayElement(
1813 static_cast<jobjectArray>(java_data->l), 0, jo_enum.get() );
1814 jni.ensure_no_exception();
1815 }
1816 }
1817 else
1818 {
1819 java_data->l = jo_enum.release();
1820 }
1821 break;
1822 }
1823 case typelib_TypeClass_STRUCT:
1824 case typelib_TypeClass_EXCEPTION:
1825 {
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 );
1830
1831 JLocalAutoRef jo_comp( jni );
1832 if (in_param)
1833 {
1834 if (type->eTypeClass == typelib_TypeClass_EXCEPTION)
1835 {
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();
1844 }
1845 else
1846 {
1847 jo_comp.reset( jni->AllocObject( comp_info->m_class ) );
1848 jni.ensure_no_exception();
1849 }
1850
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 ) )
1855 {
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--; )
1866 {
1867 jfieldID field_id = linfo->m_fields[ nPos ];
1868 if (field_id != nullptr)
1869 {
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)
1879 {
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) );
1897 }
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) );
1916 }
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) );
1935 }
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) );
1955 }
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) );
1975 }
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) );
1995 }
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) );
2014 }
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) );
2033 }
2034 break;
2035 case typelib_TypeClass_STRING: // string opt here
2036 {
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;
2043 }
2044 default:
2045 {
2046 jvalue java_data2;
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;
2054 }
2055 }
2056 }
2057 }
2058 }
2059 }
2060 if (out_param)
2061 {
2062 if (java_data->l == nullptr)
2063 {
2064 java_data->l =
2065 jni->NewObjectArray( 1, comp_info->m_class, jo_comp.get() );
2066 jni.ensure_no_exception();
2067 }
2068 else
2069 {
2070 jni->SetObjectArrayElement(
2071 static_cast<jobjectArray>(java_data->l), 0, jo_comp.get() );
2072 jni.ensure_no_exception();
2073 }
2074 }
2075 else
2076 {
2077 java_data->l = jo_comp.release();
2078 }
2079 break;
2080 }
2081 case typelib_TypeClass_SEQUENCE:
2082 {
2083 // xxx todo: possible opt for pure out sequences
2084 JLocalAutoRef jo_ar( jni );
2085
2086 sal_Int32 nElements;
2087 uno_Sequence * seq = nullptr;
2088 if (in_param)
2089 {
2090 seq = *static_cast<uno_Sequence * const *>(uno_data);
2091 nElements = seq->nElements;
2092 }
2093 else
2094 {
2095 nElements = 0;
2096 }
2097
2098 TypeDescr td( type );
2099 typelib_TypeDescriptionReference * element_type =
2100 reinterpret_cast<typelib_IndirectTypeDescription *>(td.get())->pType;
2101
2102 switch (element_type->eTypeClass)
2103 {
2104 case typelib_TypeClass_CHAR:
2105 jo_ar.reset( jni->NewCharArray( nElements ) );
2106 jni.ensure_no_exception();
2107 if (0 < nElements)
2108 {
2109 jni->SetCharArrayRegion(
2110 static_cast<jcharArray>(jo_ar.get()),
2111 0, nElements, reinterpret_cast<jchar *>(seq->elements) );
2112 jni.ensure_no_exception();
2113 }
2114 break;
2115 case typelib_TypeClass_BOOLEAN:
2116 jo_ar.reset( jni->NewBooleanArray( nElements ) );
2117 jni.ensure_no_exception();
2118 if (0 < nElements)
2119 {
2120 jni->SetBooleanArrayRegion(
2121 static_cast<jbooleanArray>(jo_ar.get()),
2122 0, nElements, reinterpret_cast<jboolean *>(seq->elements) );
2123 jni.ensure_no_exception();
2124 }
2125 break;
2126 case typelib_TypeClass_BYTE:
2127 jo_ar.reset( jni->NewByteArray( nElements ) );
2128 jni.ensure_no_exception();
2129 if (0 < nElements)
2130 {
2131 jni->SetByteArrayRegion(
2132 static_cast<jbyteArray>(jo_ar.get()),
2133 0, nElements, reinterpret_cast<jbyte *>(seq->elements) );
2134 jni.ensure_no_exception();
2135 }
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)
2142 {
2143 jni->SetShortArrayRegion(
2144 static_cast<jshortArray>(jo_ar.get()),
2145 0, nElements, reinterpret_cast<jshort *>(seq->elements) );
2146 jni.ensure_no_exception();
2147 }
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)
2154 {
2155 jni->SetIntArrayRegion(
2156 static_cast<jintArray>(jo_ar.get()),
2157 0, nElements, reinterpret_cast<jint *>(seq->elements) );
2158 jni.ensure_no_exception();
2159 }
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)
2166 {
2167 jni->SetLongArrayRegion(
2168 static_cast<jlongArray>(jo_ar.get()),
2169 0, nElements, reinterpret_cast<jlong *>(seq->elements) );
2170 jni.ensure_no_exception();
2171 }
2172 break;
2173 case typelib_TypeClass_FLOAT:
2174 jo_ar.reset( jni->NewFloatArray( nElements ) );
2175 jni.ensure_no_exception();
2176 if (0 < nElements)
2177 {
2178 jni->SetFloatArrayRegion(
2179 static_cast<jfloatArray>(jo_ar.get()),
2180 0, nElements, reinterpret_cast<jfloat *>(seq->elements) );
2181 jni.ensure_no_exception();
2182 }
2183 break;
2184 case typelib_TypeClass_DOUBLE:
2185 jo_ar.reset( jni->NewDoubleArray( nElements ) );
2186 jni.ensure_no_exception();
2187 if (0 < nElements)
2188 {
2189 jni->SetDoubleArrayRegion(
2190 static_cast<jdoubleArray>(jo_ar.get()),
2191 0, nElements, reinterpret_cast<jdouble *>(seq->elements) );
2192 jni.ensure_no_exception();
2193 }
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)
2201 {
2202 rtl_uString * const * pp =
2203 reinterpret_cast<rtl_uString * const *>(seq->elements);
2204 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2205 {
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();
2211 }
2212 }
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)
2219 {
2220 typelib_TypeDescriptionReference * const * pp =
2221 reinterpret_cast<typelib_TypeDescriptionReference * const *>(seq->elements);
2222 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2223 {
2224 jvalue val;
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();
2232 }
2233 }
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)
2241 {
2242 uno_Any const * p = reinterpret_cast<uno_Any const *>(seq->elements);
2243 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2244 {
2245 jvalue val;
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();
2253 }
2254 }
2255 break;
2256 case typelib_TypeClass_ENUM:
2257 {
2258 OUString const & element_type_name =
2259 OUString::unacquired( &element_type->pTypeName );
2260 OString class_name(
2262 element_type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
2263 JLocalAutoRef jo_enum_class(
2264 jni, find_class( jni, class_name.getStr() ) );
2265
2266 jo_ar.reset(
2267 jni->NewObjectArray(
2268 nElements, static_cast<jclass>(jo_enum_class.get()), nullptr ) );
2269 jni.ensure_no_exception();
2270
2271 if (0 < nElements)
2272 {
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 );
2279
2280 sal_Int32 const * p = reinterpret_cast<sal_Int32 const *>(seq->elements);
2281 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2282 {
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();
2292 }
2293 }
2294 break;
2295 }
2296 case typelib_TypeClass_STRUCT:
2297 case typelib_TypeClass_EXCEPTION:
2298 {
2299 JNI_type_info const * element_info =
2300 getJniInfo()->get_type_info( jni, element_type );
2301
2302 jo_ar.reset(
2303 jni->NewObjectArray( nElements, element_info->m_class, nullptr ) );
2304 jni.ensure_no_exception();
2305
2306 if (0 < nElements)
2307 {
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 )
2311 {
2312 jvalue val;
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();
2321 }
2322 }
2323 break;
2324 }
2325 case typelib_TypeClass_SEQUENCE:
2326 {
2327 OStringBuffer buf( 64 );
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() ) );
2334
2335 jo_ar.reset(
2336 jni->NewObjectArray(
2337 nElements, static_cast<jclass>(jo_seq_class.get()), nullptr ) );
2338 jni.ensure_no_exception();
2339
2340 if (0 < nElements)
2341 {
2342 uno_Sequence * const * elements = reinterpret_cast<uno_Sequence * const *>(seq->elements);
2343 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2344 {
2345 jvalue java_data2;
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();
2353 }
2354 }
2355 break;
2356 }
2357 case typelib_TypeClass_INTERFACE:
2358 {
2359 JNI_interface_type_info const * iface_info =
2360 static_cast< JNI_interface_type_info const * >(
2361 getJniInfo()->get_type_info( jni, element_type ) );
2362
2363 jo_ar.reset(
2364 jni->NewObjectArray( nElements, iface_info->m_class, nullptr ) );
2365 jni.ensure_no_exception();
2366
2367 if (0 < nElements)
2368 {
2369 uno_Interface * const * pp = reinterpret_cast<uno_Interface * const *>(seq->elements);
2370 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
2371 {
2372 uno_Interface * pUnoI = pp[ nPos ];
2373 if (pUnoI != nullptr)
2374 {
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();
2381 }
2382 }
2383 }
2384 break;
2385 }
2386 default:
2387 {
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() );
2393 }
2394 }
2395
2396 if (out_param)
2397 {
2398 if (java_data->l == nullptr)
2399 {
2400 JLocalAutoRef jo_element_class(
2401 jni, jni->GetObjectClass( jo_ar.get() ) );
2402 if (in_param)
2403 {
2404 java_data->l = jni->NewObjectArray(
2405 1, static_cast<jclass>(jo_element_class.get()), jo_ar.get() );
2406 }
2407 else
2408 {
2409 java_data->l = jni->NewObjectArray(
2410 1, static_cast<jclass>(jo_element_class.get()), nullptr );
2411 }
2412 jni.ensure_no_exception();
2413 }
2414 else
2415 {
2416 jni->SetObjectArrayElement(
2417 static_cast<jobjectArray>(java_data->l), 0, jo_ar.get() );
2418 jni.ensure_no_exception();
2419 }
2420 }
2421 else
2422 {
2423 java_data->l = jo_ar.release();
2424 }
2425 break;
2426 }
2427 case typelib_TypeClass_INTERFACE:
2428 {
2429 JLocalAutoRef jo_iface( jni );
2430 if (in_param)
2431 {
2432 uno_Interface * pUnoI = *static_cast<uno_Interface * const *>(uno_data);
2433 if (pUnoI != nullptr)
2434 {
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 ) );
2440 }
2441 }
2442 if (out_param)
2443 {
2444 if (java_data->l == nullptr)
2445 {
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();
2451 }
2452 else
2453 {
2454 jni->SetObjectArrayElement(
2455 static_cast<jobjectArray>(java_data->l), 0, jo_iface.get() );
2456 jni.ensure_no_exception();
2457 }
2458 }
2459 else
2460 {
2461 java_data->l = jo_iface.release();
2462 }
2463 break;
2464 }
2465 default:
2466 {
2467 throw BridgeRuntimeError(
2468 "[map_to_java():" + OUString::unacquired( &type->pTypeName )
2469 + "] unsupported type!" + jni.get_stack_trace() );
2470 }
2471 }
2472}
2473
2474}
2475
2476/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SAL_CALL uno_any_construct(uno_Any *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_AcquireFunc acquire) SAL_THROW_EXTERN_C()
void SAL_CALL uno_any_destruct(uno_Any *pValue, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
bool is() const
Definition: jni_base.h:158
jobject get() const
Definition: jni_base.h:156
void reset(jobject jo)
Definition: jni_base.h:185
OUString get_stack_trace(jobject jo_exc=nullptr) const
Definition: jni_bridge.cxx:376
void ensure_no_exception() const
Definition: jni_base.h:97
jmethodID m_ctor_Short_with_short
Definition: jni_info.h:164
jmethodID m_method_Integer_intValue
Definition: jni_info.h:174
jmethodID m_method_Boolean_booleanValue
Definition: jni_info.h:169
jmethodID m_ctor_Character_with_char
Definition: jni_info.h:161
jmethodID m_method_Short_shortValue
Definition: jni_info.h:176
jmethodID m_ctor_Double_with_double
Definition: jni_info.h:168
jmethodID m_method_Long_longValue
Definition: jni_info.h:175
jclass m_class_Boolean
Definition: jni_info.h:141
jmethodID m_ctor_Float_with_float
Definition: jni_info.h:167
jmethodID m_method_Double_doubleValue
Definition: jni_info.h:172
jobject m_object_Type_UNSIGNED_LONG
Definition: jni_info.h:136
jfieldID m_field_Enum_m_value
Definition: jni_info.h:189
jclass m_class_String
Definition: jni_info.h:148
jobject m_object_Type_UNSIGNED_HYPER
Definition: jni_info.h:137
jmethodID m_method_Float_floatValue
Definition: jni_info.h:173
jmethodID m_ctor_Byte_with_byte
Definition: jni_info.h:163
jmethodID m_ctor_Boolean_with_boolean
Definition: jni_info.h:162
jclass m_class_Double
Definition: jni_info.h:147
jmethodID m_ctor_Long_with_long
Definition: jni_info.h:166
JNI_type_info const * get_type_info(JNI_context const &jni, typelib_TypeDescription *type) const
Definition: jni_info.cxx:376
jclass m_class_Float
Definition: jni_info.h:146
jclass m_class_Short
Definition: jni_info.h:143
jclass m_class_Integer
Definition: jni_info.h:144
jclass m_class_Character
Definition: jni_info.h:140
jmethodID m_method_Byte_byteValue
Definition: jni_info.h:170
static void append_sig(OStringBuffer *buf, typelib_TypeDescriptionReference *type, bool use_Object_for_type_XInterface=true, bool use_slashes=true)
Definition: jni_info.h:246
jmethodID m_ctor_Integer_with_int
Definition: jni_info.h:165
jclass m_class_Long
Definition: jni_info.h:145
jclass m_class_Byte
Definition: jni_info.h:142
jobject m_object_Type_UNSIGNED_SHORT
Definition: jni_info.h:135
jmethodID m_method_Character_charValue
Definition: jni_info.h:171
typelib_TypeDescription * get() const
Definition: jni_base.h:240
sal_Int32 nElements
void SAL_CALL uno_type_destructData(void *pValue, typelib_TypeDescriptionReference *pType, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
char const * name
void * p
sal_uInt16 nPos
struct _typelib_TypeDescription typelib_TypeDescription
Definition: msvc/except.hxx:53
struct _uno_Any uno_Any
Definition: msvc/except.hxx:32
def assign(rData, bBool, cChar, nByte, nShort, nUShort, nLong, nULong, nHyper, nUHyper, fFloat, fDouble, eEnum, rStr, xTest, rAny)
int i
OUString jstring_to_oustring(JNI_context const &jni, jstring jstr)
Definition: jni_helper.h:60
void jstring_to_ustring(JNI_context const &jni, rtl_uString **out_ustr, jstring jstr)
Definition: jni_helper.h:33
bool type_equals(typelib_TypeDescriptionReference *type1, typelib_TypeDescriptionReference *type2)
Definition: jni_info.h:43
jstring ustring_to_jstring(JNI_context const &jni, rtl_uString const *ustr)
Definition: jni_helper.h:68
jclass find_class(JNI_context const &jni, char const *class_name, bool inException=false)
Definition: jni_helper.h:79
jobject create_type(JNI_context const &jni, jclass clazz)
Definition: jni_helper.h:102
bool is_XInterface(typelib_TypeDescriptionReference *type)
Definition: jni_info.h:56
static std::unique_ptr< rtl_mem > seq_allocate(sal_Int32 nElements, sal_Int32 nSize)
Definition: jni_data.cxx:34
args
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
typelib_TypeDescriptionReference **SAL_CALL typelib_static_type_getByTypeClass(typelib_TypeClass eTypeClass) SAL_THROW_EXTERN_C()
void map_to_java(JNI_context const &jni, jvalue *java_data, void const *uno_data, typelib_TypeDescriptionReference *type, JNI_type_info const *info, bool in_param, bool out_param, bool special_wrapped_integral_types=false) const
Definition: jni_data.cxx:1155
void map_to_uno(JNI_context const &jni, void *uno_data, jvalue java_data, typelib_TypeDescriptionReference *type, JNI_type_info const *info, bool assign, bool out_param, bool special_wrapped_integral_types=false) const
Definition: jni_data.cxx:211
JNI_info const * getJniInfo() const
Definition: jni_bridge.cxx:270
std::unique_ptr< jfieldID[]> m_fields
Definition: jni_info.h:100
JNI_type_info const * m_base
Definition: jni_info.h:96
::com::sun::star::uno::TypeDescription m_td
Definition: jni_info.h:67
static rtl_mem * allocate(std::size_t bytes)
Definition: jni_base.h:219
void SAL_CALL typelib_typedescriptionreference_acquire(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
void SAL_CALL typelib_typedescriptionreference_assign(typelib_TypeDescriptionReference **ppDest, typelib_TypeDescriptionReference *pSource) SAL_THROW_EXTERN_C()
void SAL_CALL typelib_typedescriptionreference_release(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
unsigned char sal_Bool
#define SAL_SEQUENCE_HEADER_SIZE
sal_uInt16 sal_Unicode
signed char sal_Int8
ResultType type